LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
MuonLeadingEventValidationAlgorithm.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 
15 
17 
18 #include <sstream>
19 
20 using namespace pandora;
21 
22 namespace lar_content
23 {
24 
25 MuonLeadingEventValidationAlgorithm::MuonLeadingEventValidationAlgorithm() :
26  m_removeRecoCosmicRayHits(false),
27  m_deltaRayMode(false),
28  m_michelMode(false),
29  m_cosmicRaysToSkip(0),
30  m_visualize(false),
31  m_ignoreIncorrectCosmicRays(false),
32  m_writeRawMatchesToTree(false)
33 {
34 }
35 
36 //------------------------------------------------------------------------------------------------------------------------------------------
37 
39 {
40 }
41 
42 //------------------------------------------------------------------------------------------------------------------------------------------
43 
44 void MuonLeadingEventValidationAlgorithm::FillValidationInfo(const MCParticleList *const pMCParticleList,
45  const CaloHitList *const pCaloHitList, const PfoList *const pPfoList, ValidationInfo &validationInfo) const
46 {
47  if (!(m_michelMode || m_deltaRayMode))
48  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
49 
50  if (m_visualize)
51  {
52 #ifdef MONITORING
53  PandoraMonitoringApi::SetEveDisplayParameters(this->GetPandora(), true, DETECTOR_VIEW_DEFAULT, -1.f, 1.f, 1.f);
54 #endif
55  }
56 
57  CaloHitList recoCosmicRayHitList;
59  this->GetRecoCosmicRayHits(pMCParticleList, pCaloHitList, pPfoList, recoCosmicRayHitList);
60 
62  pMCParticleList, pCaloHitList, pPfoList, recoCosmicRayHitList, m_validationParameters.m_minHitSharingFraction, validationInfo);
63 
65  this->RemoveIncorrectlyReconstructedCosmicRays(pMCParticleList, pCaloHitList, pPfoList, validationInfo);
66 }
67 
68 //------------------------------------------------------------------------------------------------------------------------------------------
69 
70 void MuonLeadingEventValidationAlgorithm::GetRecoCosmicRayHits(const MCParticleList *const pMCParticleList,
71  const CaloHitList *const pCaloHitList, const PfoList *const pPfoList, CaloHitList &recoCosmicRayHitList) const
72 {
73  recoCosmicRayHitList.clear();
74 
75  ValidationInfo validationInfo;
76  this->PerformUnfoldedMatching(pMCParticleList, pCaloHitList, pPfoList, recoCosmicRayHitList, 0.f, validationInfo);
77 
78  const LArMCParticleHelper::MCContributionMap &allMCToHitsMap(validationInfo.GetAllMCParticleToHitsMap());
79  const LArMCParticleHelper::PfoContributionMap &pfoToHitsMap(validationInfo.GetPfoToHitsMap());
80  const LArMCParticleHelper::MCParticleToPfoHitSharingMap &interpretedMatchingMap(validationInfo.GetInterpretedMCToPfoHitSharingMap());
81 
82  for (auto &entry : allMCToHitsMap)
83  {
84  if (!LArMCParticleHelper::IsCosmicRay(entry.first))
85  continue;
86 
87  const MCParticle *const pCosmicRay(entry.first);
88 
89  for (LArMCParticleHelper::PfoToSharedHitsVector::const_iterator cosmicRayMatchedPfoPair = interpretedMatchingMap.at(pCosmicRay).begin();
90  cosmicRayMatchedPfoPair != interpretedMatchingMap.at(pCosmicRay).end(); ++cosmicRayMatchedPfoPair)
91  {
92  const ParticleFlowObject *const pCosmicRayPfo(cosmicRayMatchedPfoPair->first);
93  recoCosmicRayHitList.insert(recoCosmicRayHitList.end(), pfoToHitsMap.at(pCosmicRayPfo).begin(), pfoToHitsMap.at(pCosmicRayPfo).end());
94  }
95  }
96 }
97 
98 //------------------------------------------------------------------------------------------------------------------------------------------
99 
100 void MuonLeadingEventValidationAlgorithm::PerformUnfoldedMatching(const MCParticleList *const pMCParticleList, const CaloHitList *const pCaloHitList,
101  const PfoList *const pPfoList, const CaloHitList &recoCosmicRayHitList, const float minHitSharingFraction, ValidationInfo &validationInfo) const
102 {
103  if (pMCParticleList && pCaloHitList)
104  {
105  // Get reconstructable MCParticle hit ownership map (non-muon leading hierarchy is folded whilst muon is unfolded)
107  validationParams.m_minHitSharingFraction = minHitSharingFraction;
108  LArMCParticleHelper::MCContributionMap targetMCParticleToHitsMap;
110  pMCParticleList, pCaloHitList, validationParams, recoCosmicRayHitList, targetMCParticleToHitsMap);
111 
112  // Do not change the hit share fraction (these hits are classed as 'ambiguous' and should not be in the metrics)
114  allValidationParams.m_minPrimaryGoodHits = 0;
115  allValidationParams.m_minHitsForGoodView = 0;
116  allValidationParams.m_minHitSharingFraction = minHitSharingFraction;
117  LArMCParticleHelper::MCContributionMap allMCParticleToHitsMap;
119  pMCParticleList, pCaloHitList, allValidationParams, recoCosmicRayHitList, allMCParticleToHitsMap);
120 
121  validationInfo.SetTargetMCParticleToHitsMap(targetMCParticleToHitsMap);
122  validationInfo.SetAllMCParticleToHitsMap(allMCParticleToHitsMap);
123  }
124 
125  // ATTN: Can only do this because delta ray/michel hierarchy is folded back in reconstruction
126  if (pPfoList)
127  {
129  LArMCParticleHelper::GetPfoToReconstructable2DHitsMap(*pPfoList, validationInfo.GetAllMCParticleToHitsMap(), pfoToHitsMap, false);
130 
131  validationInfo.SetPfoToHitsMap(pfoToHitsMap);
132  }
133 
137  validationInfo.GetPfoToHitsMap(), {validationInfo.GetAllMCParticleToHitsMap()}, pfoToMCHitSharingMap, mcToPfoHitSharingMap);
138 
139  validationInfo.SetMCToPfoHitSharingMap(mcToPfoHitSharingMap);
140 
141  LArMCParticleHelper::MCParticleToPfoHitSharingMap interpretedMCToPfoHitSharingMap;
142  this->InterpretMatching(validationInfo, interpretedMCToPfoHitSharingMap);
143 
144  validationInfo.SetInterpretedMCToPfoHitSharingMap(interpretedMCToPfoHitSharingMap);
145 }
146 
147 //------------------------------------------------------------------------------------------------------------------------------------------
148 
150  const CaloHitList *const pCaloHitList, const PfoList *const pPfoList, ValidationInfo &validationInfo) const
151 {
152  MCParticleList incorrectlyReconstructedCosmicRays;
153  this->DetermineIncorrectlyReconstructedCosmicRays(pMCParticleList, pCaloHitList, pPfoList, incorrectlyReconstructedCosmicRays);
154 
155  LArMCParticleHelper::MCContributionMap allMCToHitsMap(validationInfo.GetAllMCParticleToHitsMap());
156  LArMCParticleHelper::MCContributionMap targetMCToHitsMap(validationInfo.GetTargetMCParticleToHitsMap());
159 
160  for (const MCParticle *const pIncorrectCosmicRay : incorrectlyReconstructedCosmicRays)
161  {
162  auto allIter(allMCToHitsMap.find(pIncorrectCosmicRay));
163 
164  if (allIter != allMCToHitsMap.end())
165  allMCToHitsMap.erase(allIter);
166 
167  auto targetIter(targetMCToHitsMap.find(pIncorrectCosmicRay));
168 
169  if (targetIter != targetMCToHitsMap.end())
170  targetMCToHitsMap.erase(targetIter);
171 
172  auto matchingIter(matchingMap.find(pIncorrectCosmicRay));
173 
174  if (matchingIter != matchingMap.end())
175  matchingMap.erase(matchingIter);
176 
177  auto interpretedMatchingIter(interpretedMatchingMap.find(pIncorrectCosmicRay));
178 
179  if (interpretedMatchingIter != interpretedMatchingMap.end())
180  interpretedMatchingMap.erase(interpretedMatchingIter);
181  }
182 
183  validationInfo.SetAllMCParticleToHitsMap(allMCToHitsMap);
184  validationInfo.SetTargetMCParticleToHitsMap(targetMCToHitsMap);
185  validationInfo.SetMCToPfoHitSharingMap(matchingMap);
186  validationInfo.SetInterpretedMCToPfoHitSharingMap(interpretedMatchingMap);
187 }
188 
189 //------------------------------------------------------------------------------------------------------------------------------------------
190 
192  const CaloHitList *const pCaloHitList, const PfoList *const pPfoList, MCParticleList &incorrectlyReconstructedCosmicRays) const
193 {
194  // Perform cosmic ray matching
195  CaloHitList recoCosmicRayHitList;
196  ValidationInfo validationInfo;
197  this->PerformUnfoldedMatching(pMCParticleList, pCaloHitList, pPfoList, recoCosmicRayHitList, 0.f, validationInfo);
198 
199  const LArMCParticleHelper::MCContributionMap &allMCToHitsMap(validationInfo.GetAllMCParticleToHitsMap());
200  const LArMCParticleHelper::MCContributionMap &targetMCToHitsMap(validationInfo.GetTargetMCParticleToHitsMap());
201  const LArMCParticleHelper::PfoContributionMap &pfoToHitsMap(validationInfo.GetPfoToHitsMap());
202  const LArMCParticleHelper::MCParticleToPfoHitSharingMap &interpretedMatchingMap(validationInfo.GetInterpretedMCToPfoHitSharingMap());
203 
204  // Determine incorrectly reconstructed cosmic rays
205  MCParticleVector targetCosmicRayVector;
206  LArMonitoringHelper::GetOrderedMCParticleVector({targetMCToHitsMap}, targetCosmicRayVector);
207 
208  for (const MCParticle *const pTargetCosmicRay : targetCosmicRayVector)
209  {
210  if (!LArMCParticleHelper::IsCosmicRay(pTargetCosmicRay))
211  continue;
212 
213  if (interpretedMatchingMap.at(pTargetCosmicRay).empty())
214  {
215  incorrectlyReconstructedCosmicRays.push_back(pTargetCosmicRay);
216  continue;
217  }
218 
219  const CaloHitList &mcHitList(allMCToHitsMap.at(pTargetCosmicRay));
220 
221  unsigned int nAboveThresholdMatches(0);
222  for (const LArMCParticleHelper::PfoCaloHitListPair &pfoToSharedHits : interpretedMatchingMap.at(pTargetCosmicRay))
223  {
224  const CaloHitList &sharedHitList(pfoToSharedHits.second);
225  const CaloHitList &pfoHitList(pfoToHitsMap.at(pfoToSharedHits.first));
226 
227  const bool isGoodMatch(this->IsGoodMatch(mcHitList, pfoHitList, sharedHitList));
228 
229  if (isGoodMatch)
230  ++nAboveThresholdMatches;
231  }
232 
233  if (nAboveThresholdMatches != 1)
234  incorrectlyReconstructedCosmicRays.push_back(pTargetCosmicRay);
235  }
236 }
237 
238 //------------------------------------------------------------------------------------------------------------------------------------------
239 
241  const ValidationInfo &validationInfo, const bool useInterpretedMatching, const bool printToScreen, const bool fillTree) const
242 {
243  const LArMCParticleHelper::MCContributionMap &foldedAllMCToHitsMap(validationInfo.GetAllMCParticleToHitsMap());
244  const LArMCParticleHelper::MCContributionMap &foldedTargetMCToHitsMap(validationInfo.GetTargetMCParticleToHitsMap());
245  const LArMCParticleHelper::PfoContributionMap &foldedPfoToHitsMap(validationInfo.GetPfoToHitsMap());
246  const LArMCParticleHelper::MCParticleToPfoHitSharingMap &foldedMCToPfoHitSharingMap((fillTree && m_writeRawMatchesToTree)
247  ? validationInfo.GetMCToPfoHitSharingMap()
248  : useInterpretedMatching ? validationInfo.GetInterpretedMCToPfoHitSharingMap()
249  : validationInfo.GetMCToPfoHitSharingMap());
250 
251  // Consider only delta rays from reconstructable CR muons
252  MCParticleVector mcCRVector;
253  for (auto &entry : foldedTargetMCToHitsMap)
254  {
255  if (LArMCParticleHelper::IsCosmicRay(entry.first))
256  mcCRVector.push_back(entry.first);
257  }
258 
259  std::sort(mcCRVector.begin(), mcCRVector.end(), LArMCParticleHelper::SortByMomentum);
260 
261  // Process matches
262  int muonCount(0);
263  std::stringstream stringStream;
264 
265  for (const MCParticle *const pCosmicRay : mcCRVector)
266  {
267  // Move on if cosmic ray has not been reconstructed
268  if (foldedMCToPfoHitSharingMap.at(pCosmicRay).empty())
269  continue;
270 
271  // Cosmic ray parameters
272  int nReconstructableChildCRLs(0), nCorrectChildCRLs(0);
273 
274 #ifdef MONITORING
275  int ID_CR(0);
276  float mcE_CR(0.f), mcPX_CR(0.f), mcPY_CR(0.f), mcPZ_CR(0.f);
277  int nMCHitsTotal_CR(0), nMCHitsU_CR(0), nMCHitsV_CR(0), nMCHitsW_CR(0);
278  float mcVertexX_CR(0.f), mcVertexY_CR(0.f), mcVertexZ_CR(0.f), mcEndX_CR(0.f), mcEndY_CR(0.f), mcEndZ_CR(0.f);
279 #endif
280 
281  // Leading particle parameters
282  FloatVector mcE_CRL, mcPX_CRL, mcPY_CRL, mcPZ_CRL;
283  IntVector ID_CRL;
284  IntVector nMCHitsTotal_CRL, nMCHitsU_CRL, nMCHitsV_CRL, nMCHitsW_CRL;
285  FloatVector mcVertexX_CRL, mcVertexY_CRL, mcVertexZ_CRL, mcEndX_CRL, mcEndY_CRL, mcEndZ_CRL;
286  IntVector nAboveThresholdMatches_CRL, isCorrect_CRL, isCorrectParentLink_CRL;
287  IntVector bestMatchNHitsTotal_CRL, bestMatchNHitsU_CRL, bestMatchNHitsV_CRL, bestMatchNHitsW_CRL;
288  IntVector bestMatchNSharedHitsTotal_CRL, bestMatchNSharedHitsU_CRL, bestMatchNSharedHitsV_CRL, bestMatchNSharedHitsW_CRL;
289  IntVector bestMatchNParentTrackHitsTotal_CRL, bestMatchNParentTrackHitsU_CRL, bestMatchNParentTrackHitsV_CRL, bestMatchNParentTrackHitsW_CRL;
290  IntVector bestMatchNOtherTrackHitsTotal_CRL, bestMatchNOtherTrackHitsU_CRL, bestMatchNOtherTrackHitsV_CRL, bestMatchNOtherTrackHitsW_CRL;
291  IntVector bestMatchNOtherShowerHitsTotal_CRL, bestMatchNOtherShowerHitsU_CRL, bestMatchNOtherShowerHitsV_CRL, bestMatchNOtherShowerHitsW_CRL;
292  IntVector totalCRLHitsInBestMatchParentCR_CRL, uCRLHitsInBestMatchParentCR_CRL, vCRLHitsInBestMatchParentCR_CRL, wCRLHitsInBestMatchParentCR_CRL;
293  FloatVector bestMatchVertexX_CRL, bestMatchVertexY_CRL, bestMatchVertexZ_CRL;
294 
295  // Contamination parameters
296  IntVector bestMatchOtherShowerHitsID_CRL, bestMatchOtherTrackHitsID_CRL, bestMatchParentTrackHitsID_CRL, bestMatchCRLHitsInCRID_CRL;
297  FloatVector bestMatchOtherShowerHitsDistance_CRL, bestMatchOtherTrackHitsDistance_CRL, bestMatchParentTrackHitsDistance_CRL,
298  bestMatchCRLHitsInCRDistance_CRL;
299 
300  // Obtain reconstructable leading particles
301  MCParticleVector childLeadingParticles;
302 
303  for (const MCParticle *const pCosmicRayChild : pCosmicRay->GetDaughterList())
304  {
305  if (!m_deltaRayIDs.empty())
306  {
307  int mcIndex((size_t)(intptr_t *)pCosmicRayChild->GetUid());
308 
309  if (std::find(m_deltaRayIDs.begin(), m_deltaRayIDs.end(), mcIndex) == m_deltaRayIDs.end())
310  continue;
311  }
312 
313  if (m_deltaRayMode && (!LArMuonLeadingHelper::IsDeltaRay(pCosmicRayChild)))
314  continue;
315 
316  if (m_michelMode && (!LArMuonLeadingHelper::IsMichel(pCosmicRayChild)))
317  continue;
318 
319  // Move on if leading particle is not reconstructable
320  if (foldedTargetMCToHitsMap.find(pCosmicRayChild) == foldedTargetMCToHitsMap.end())
321  continue;
322 
323  childLeadingParticles.push_back(pCosmicRayChild);
324  }
325 
326  // Move on if cosmic ray has no leading delta ray child particles
327  if (childLeadingParticles.empty())
328  continue;
329 
330  std::sort(childLeadingParticles.begin(), childLeadingParticles.end(), LArMCParticleHelper::SortByMomentum);
331 
332  ++muonCount;
333 
334  if (muonCount < (m_cosmicRaysToSkip))
335  continue;
336 
337  // Pull cosmic ray info
338  const CaloHitList &cosmicRayHitList(foldedAllMCToHitsMap.at(pCosmicRay));
339 
341  if (m_visualize && useInterpretedMatching)
342  {
343 #ifdef MONITORING
344  std::cout << "MC COSMIC RAY HITS" << std::endl;
345  this->PrintHits(cosmicRayHitList, true);
346 
347  const CartesianVector vertex(pCosmicRay->GetVertex()), endpoint(pCosmicRay->GetEndpoint());
348  const float x0(cosmicRayHitList.front()->GetX0());
349  const CartesianVector shiftedVertex(vertex.GetX() - x0, vertex.GetY(), vertex.GetZ());
350  const CartesianVector shiftedEndpoint(endpoint.GetX() - x0, vertex.GetY(), vertex.GetZ());
351 
352  PandoraMonitoringApi::AddMarkerToVisualization(this->GetPandora(), &shiftedVertex, "T0 shifted vertex ", BLACK, 2);
353  PandoraMonitoringApi::AddMarkerToVisualization(this->GetPandora(), &shiftedEndpoint, "T0 shifted endpoint", BLACK, 2);
354  PandoraMonitoringApi::ViewEvent(this->GetPandora());
355 #endif
356  }
358 
359 #ifdef MONITORING
360  ID_CR = muonCount;
361  mcE_CR = pCosmicRay->GetEnergy();
362  mcPX_CR = pCosmicRay->GetMomentum().GetX();
363  mcPY_CR = pCosmicRay->GetMomentum().GetY();
364  mcPZ_CR = pCosmicRay->GetMomentum().GetZ();
365  mcVertexX_CR = pCosmicRay->GetVertex().GetX();
366  mcVertexY_CR = pCosmicRay->GetVertex().GetY();
367  mcVertexZ_CR = pCosmicRay->GetVertex().GetZ();
368  mcEndX_CR = pCosmicRay->GetEndpoint().GetX();
369  mcEndY_CR = pCosmicRay->GetEndpoint().GetY();
370  mcEndZ_CR = pCosmicRay->GetEndpoint().GetZ();
371  nMCHitsTotal_CR = cosmicRayHitList.size();
372  nMCHitsU_CR = LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, cosmicRayHitList);
373  nMCHitsV_CR = LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, cosmicRayHitList);
374  nMCHitsW_CR = LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, cosmicRayHitList);
375 #endif
376  nReconstructableChildCRLs = childLeadingParticles.size();
377 
378  stringStream << "\033[34m"
379  << "(Parent CR: " << muonCount << ") "
380  << "\033[0m"
381  << "Energy " << pCosmicRay->GetEnergy() << ", Dist. " << (pCosmicRay->GetEndpoint() - pCosmicRay->GetVertex()).GetMagnitude()
382  << ", nMCHits " << cosmicRayHitList.size() << " (" << LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, cosmicRayHitList)
383  << ", " << LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, cosmicRayHitList) << ", "
384  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, cosmicRayHitList) << ")"
385  << ", nReconstructableCRLs " << nReconstructableChildCRLs << std::endl;
386 
387  // Pull delta ray info
388  int leadingCount(0);
389 
390  for (const MCParticle *const pLeadingParticle : childLeadingParticles)
391  {
392  ++leadingCount;
393 
394  // Pull delta ray MC info
395  const CaloHitList &leadingParticleHitList(foldedAllMCToHitsMap.at(pLeadingParticle));
396 
398  if (m_visualize && useInterpretedMatching)
399  {
400 #ifdef MONITORING
401  size_t mcIndex((size_t)(intptr_t *)pLeadingParticle->GetUid());
402 
403  std::cout << "mcID: " << mcIndex << std::endl;
404  std::cout << "MC DELTA RAY HITS" << std::endl;
405 
406  this->PrintHits(leadingParticleHitList, false);
407 
408  const CartesianVector vertex(pLeadingParticle->GetVertex()), endpoint(pLeadingParticle->GetEndpoint());
409  const float x0(leadingParticleHitList.front()->GetX0());
410  const CartesianVector shiftedVertex(vertex.GetX() - x0, vertex.GetY(), vertex.GetZ());
411  const CartesianVector shiftedEndpoint(endpoint.GetX() - x0, vertex.GetY(), vertex.GetZ());
412 
413  PandoraMonitoringApi::AddMarkerToVisualization(this->GetPandora(), &shiftedVertex, "T0 shifted vertex", BLACK, 2);
414  PandoraMonitoringApi::AddMarkerToVisualization(this->GetPandora(), &shiftedEndpoint, "T0 shifted endpoint", BLACK, 2);
415  PandoraMonitoringApi::ViewEvent(this->GetPandora());
416 #endif
417  }
419 
420  mcE_CRL.push_back(pLeadingParticle->GetEnergy());
421  ID_CRL.push_back(leadingCount);
422  mcPX_CRL.push_back(pLeadingParticle->GetMomentum().GetX());
423  mcPY_CRL.push_back(pLeadingParticle->GetMomentum().GetY());
424  mcPZ_CRL.push_back(pLeadingParticle->GetMomentum().GetZ());
425  mcVertexX_CRL.push_back(pLeadingParticle->GetVertex().GetX());
426  mcVertexY_CRL.push_back(pLeadingParticle->GetVertex().GetY());
427  mcVertexZ_CRL.push_back(pLeadingParticle->GetVertex().GetZ());
428  mcEndX_CRL.push_back(pLeadingParticle->GetEndpoint().GetX());
429  mcEndY_CRL.push_back(pLeadingParticle->GetEndpoint().GetY());
430  mcEndZ_CRL.push_back(pLeadingParticle->GetEndpoint().GetZ());
431  nMCHitsTotal_CRL.push_back(leadingParticleHitList.size());
432  nMCHitsU_CRL.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, leadingParticleHitList));
433  nMCHitsV_CRL.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, leadingParticleHitList));
434  nMCHitsW_CRL.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, leadingParticleHitList));
435 
436  stringStream << "\033[33m"
437  << "(Child " << (m_deltaRayMode ? "DR: " : "Michel: ") << leadingCount << ") "
438  << "\033[0m"
439  << "Energy " << pLeadingParticle->GetEnergy() << ", Dist. "
440  << (pLeadingParticle->GetEndpoint() - pLeadingParticle->GetVertex()).GetMagnitude() << ", nMCHits "
441  << leadingParticleHitList.size() << " (" << LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, leadingParticleHitList)
442  << ", " << LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, leadingParticleHitList) << ", "
443  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, leadingParticleHitList) << ")" << std::endl;
444 
445  // Look at the pfo matches
446  int nMatches(0), nAboveThresholdMatches(0);
447  bool isCorrectParentLink(false);
448 
449  for (const LArMCParticleHelper::PfoCaloHitListPair &pfoToSharedHits : foldedMCToPfoHitSharingMap.at(pLeadingParticle))
450  {
451  ++nMatches;
452 
453  const ParticleFlowObject *const pMatchedPfo(pfoToSharedHits.first);
454  const CaloHitList &pfoHitList(foldedPfoToHitsMap.at(pMatchedPfo));
455  const CaloHitList &sharedHitList(pfoToSharedHits.second);
456  const bool isGoodMatch(this->IsGoodMatch(leadingParticleHitList, pfoHitList, sharedHitList));
457 
458  if (isGoodMatch)
459  ++nAboveThresholdMatches;
460 
461  CaloHitList parentTrackHits, otherTrackHits, otherShowerHits;
462  LArMuonLeadingHelper::GetPfoMatchContamination(pLeadingParticle, pfoHitList, parentTrackHits, otherTrackHits, otherShowerHits);
463 
464  // Check whether the reconstructed pfo has the correct parent-child link
465  CaloHitList mcParentMatchedPfoHits;
466  bool isMatchedToCorrectCosmicRay(false);
467  const ParticleFlowObject *const pParentPfo(LArPfoHelper::GetParentPfo(pMatchedPfo));
468 
470  foldedMCToPfoHitSharingMap.at(pCosmicRay).begin();
471  cosmicRayMatchedPfoPair != foldedMCToPfoHitSharingMap.at(pCosmicRay).end(); ++cosmicRayMatchedPfoPair)
472  {
473  const ParticleFlowObject *const pCosmicRayPfo(cosmicRayMatchedPfoPair->first);
474 
475  mcParentMatchedPfoHits.insert(mcParentMatchedPfoHits.end(), foldedPfoToHitsMap.at(pCosmicRayPfo).begin(),
476  foldedPfoToHitsMap.at(pCosmicRayPfo).end());
477 
478  if (pCosmicRayPfo == pParentPfo)
479  isMatchedToCorrectCosmicRay = true;
480  }
481 
482  CaloHitList leadingParticleHitsInParentCosmicRay;
484  mcParentMatchedPfoHits, leadingParticleHitList, leadingParticleHitsInParentCosmicRay);
485 
486  if ((nAboveThresholdMatches == 1) && isGoodMatch)
487  {
488  isCorrectParentLink = isMatchedToCorrectCosmicRay;
489 
490  bestMatchNHitsTotal_CRL.push_back(pfoHitList.size());
491  bestMatchNHitsU_CRL.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, pfoHitList));
492  bestMatchNHitsV_CRL.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, pfoHitList));
493  bestMatchNHitsW_CRL.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, pfoHitList));
494 
495  bestMatchNSharedHitsTotal_CRL.push_back(sharedHitList.size());
496  bestMatchNSharedHitsU_CRL.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, sharedHitList));
497  bestMatchNSharedHitsV_CRL.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, sharedHitList));
498  bestMatchNSharedHitsW_CRL.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, sharedHitList));
499 
500  bestMatchNParentTrackHitsTotal_CRL.push_back(parentTrackHits.size());
501  bestMatchNParentTrackHitsU_CRL.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, parentTrackHits));
502  bestMatchNParentTrackHitsV_CRL.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, parentTrackHits));
503  bestMatchNParentTrackHitsW_CRL.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, parentTrackHits));
504 
505  bestMatchNOtherTrackHitsTotal_CRL.push_back(otherTrackHits.size());
506  bestMatchNOtherTrackHitsU_CRL.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, otherTrackHits));
507  bestMatchNOtherTrackHitsV_CRL.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, otherTrackHits));
508  bestMatchNOtherTrackHitsW_CRL.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, otherTrackHits));
509 
510  bestMatchNOtherShowerHitsTotal_CRL.push_back(otherShowerHits.size());
511  bestMatchNOtherShowerHitsU_CRL.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, otherShowerHits));
512  bestMatchNOtherShowerHitsV_CRL.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, otherShowerHits));
513  bestMatchNOtherShowerHitsW_CRL.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, otherShowerHits));
514 
515  totalCRLHitsInBestMatchParentCR_CRL.push_back(leadingParticleHitsInParentCosmicRay.size());
516  uCRLHitsInBestMatchParentCR_CRL.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, leadingParticleHitsInParentCosmicRay));
517  vCRLHitsInBestMatchParentCR_CRL.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, leadingParticleHitsInParentCosmicRay));
518  wCRLHitsInBestMatchParentCR_CRL.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, leadingParticleHitsInParentCosmicRay));
519 
520  bestMatchOtherShowerHitsID_CRL.insert(bestMatchOtherShowerHitsID_CRL.end(), otherShowerHits.size(), leadingCount);
521  this->FillContaminationHitsDistance(otherShowerHits, leadingParticleHitList, bestMatchOtherShowerHitsDistance_CRL);
522 
523  bestMatchOtherTrackHitsID_CRL.insert(bestMatchOtherTrackHitsID_CRL.end(), otherTrackHits.size(), leadingCount);
524  this->FillContaminationHitsDistance(otherTrackHits, leadingParticleHitList, bestMatchOtherTrackHitsDistance_CRL);
525 
526  bestMatchParentTrackHitsID_CRL.insert(bestMatchParentTrackHitsID_CRL.end(), parentTrackHits.size(), leadingCount);
527  this->FillContaminationHitsDistance(parentTrackHits, leadingParticleHitList, bestMatchParentTrackHitsDistance_CRL);
528 
529  bestMatchCRLHitsInCRID_CRL.insert(bestMatchCRLHitsInCRID_CRL.end(), leadingParticleHitsInParentCosmicRay.size(), leadingCount);
530  this->FillContaminationHitsDistance(leadingParticleHitsInParentCosmicRay, cosmicRayHitList, bestMatchCRLHitsInCRDistance_CRL);
531 
532  const VertexList &deltaRayVertexList(pMatchedPfo->GetVertexList());
533 
534  if (deltaRayVertexList.size() > 1)
535  {
536  std::cout << "ISOBEL: DELTA RAY RECO VERTEX LIST LARGER THAN 1" << std::endl;
537  throw;
538  }
539 
540  bestMatchVertexX_CRL.push_back(deltaRayVertexList.empty() ? 1000001 : deltaRayVertexList.front()->GetPosition().GetX());
541  bestMatchVertexY_CRL.push_back(deltaRayVertexList.empty() ? 1000001 : deltaRayVertexList.front()->GetPosition().GetY());
542  bestMatchVertexZ_CRL.push_back(deltaRayVertexList.empty() ? 1000001 : deltaRayVertexList.front()->GetPosition().GetZ());
543  }
544 
545  stringStream << "-" << (!isGoodMatch ? "(Below threshold) " : "") << "nPfoHits " << pfoHitList.size() << " ("
546  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, pfoHitList) << ", "
547  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, pfoHitList) << ", "
548  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, pfoHitList) << ")"
549  << ", nMatchedHits " << sharedHitList.size() << " (" << LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, sharedHitList)
550  << ", " << LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, sharedHitList) << ", "
551  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, sharedHitList) << ")"
552  << ", nCRLHitsInParentCR " << leadingParticleHitsInParentCosmicRay.size() << " ("
553  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, leadingParticleHitsInParentCosmicRay) << ", "
554  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, leadingParticleHitsInParentCosmicRay) << ", "
555  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, leadingParticleHitsInParentCosmicRay) << ")" << std::endl
556  << (!isGoodMatch ? " " : " ") << "nParentTrackHits " << parentTrackHits.size() << " ("
557  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, parentTrackHits) << ", "
558  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, parentTrackHits) << ", "
559  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, parentTrackHits) << ")"
560  << ", nOtherTrackHits " << otherTrackHits.size() << " ("
561  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, otherTrackHits) << ", "
562  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, otherTrackHits) << ", "
563  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, otherTrackHits) << ")"
564  << ", nOtherShowerHits " << otherShowerHits.size() << " ("
565  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, otherShowerHits) << ", "
566  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, otherShowerHits) << ", "
567  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, otherShowerHits) << ")" << std::endl
568  << (!isGoodMatch ? " " : " ") << (isMatchedToCorrectCosmicRay ? "Correct" : "Incorrect") << "\033[0m"
569  << " parent link" << std::endl;
570 
572  if (m_visualize && useInterpretedMatching)
573  {
574 #ifdef MONITORING
575  std::cout << stringStream.str() << std::endl;
576  std::cout << "DELTA RAY PFO HITS" << std::endl;
577 
578  this->PrintHits(pfoHitList, otherShowerHits, otherTrackHits, parentTrackHits, "DR_PFO");
579 
580  if (pParentPfo != pMatchedPfo)
581  {
582  std::cout << "PARENT PFO" << std::endl;
583 
584  const CaloHitList &parentCRHits(foldedPfoToHitsMap.at(pParentPfo));
585  this->PrintHits(parentCRHits, leadingParticleHitList, "DR_PARENT_PFO");
586  }
587 
588  const VertexList &deltaRayVertexList(pMatchedPfo->GetVertexList());
589 
590  if (deltaRayVertexList.size() > 1)
591  {
592  std::cout << "ISOBEL: DELTA RAY RECO VERTEX LIST LARGER THAN 1" << std::endl;
593  throw;
594  }
595 
596  if (deltaRayVertexList.empty())
597  {
598  std::cout << "No reconstructed vertex" << std::endl;
599  }
600  else
601  {
602  const PfoList deltaRayList({pMatchedPfo}), cosmicList({pParentPfo});
603  const CartesianVector &vertex(deltaRayVertexList.front()->GetPosition());
604 
605  PandoraMonitoringApi::VisualizeParticleFlowObjects(this->GetPandora(), &deltaRayList, "Delta Ray Pfo", BLACK, false, false);
606  PandoraMonitoringApi::VisualizeParticleFlowObjects(this->GetPandora(), &cosmicList, "Delta Ray Pfo", RED, false, false);
607  PandoraMonitoringApi::AddMarkerToVisualization(this->GetPandora(), &vertex, "vertex", RED, 2);
608  PandoraMonitoringApi::ViewEvent(this->GetPandora());
609  }
610 #endif
611  }
613  }
614 
615  nAboveThresholdMatches_CRL.push_back(nAboveThresholdMatches);
616  isCorrectParentLink_CRL.push_back(isCorrectParentLink ? 1 : 0);
617 
618  const bool isCorrect((nAboveThresholdMatches == 1) && isCorrectParentLink);
619 
620  if (isCorrect)
621  {
622  ++nCorrectChildCRLs;
623  isCorrect_CRL.push_back(1);
624  }
625  else
626  {
627  isCorrect_CRL.push_back(0);
628  }
629 
630  if (foldedMCToPfoHitSharingMap.at(pLeadingParticle).empty())
631  {
632  stringStream << "-"
633  << "No matched pfo" << std::endl;
634 
635  if (m_visualize && useInterpretedMatching)
636  std::cout << stringStream.str() << std::endl;
637  }
638 
639  if (nAboveThresholdMatches == 0)
640  {
641  bestMatchNHitsTotal_CRL.push_back(0);
642  bestMatchNHitsU_CRL.push_back(0);
643  bestMatchNHitsV_CRL.push_back(0);
644  bestMatchNHitsW_CRL.push_back(0);
645  bestMatchNSharedHitsTotal_CRL.push_back(0);
646  bestMatchNSharedHitsU_CRL.push_back(0);
647  bestMatchNSharedHitsV_CRL.push_back(0);
648  bestMatchNSharedHitsW_CRL.push_back(0);
649  bestMatchNParentTrackHitsTotal_CRL.push_back(0);
650  bestMatchNParentTrackHitsU_CRL.push_back(0);
651  bestMatchNParentTrackHitsV_CRL.push_back(0);
652  bestMatchNParentTrackHitsW_CRL.push_back(0);
653  bestMatchNOtherTrackHitsTotal_CRL.push_back(0);
654  bestMatchNOtherTrackHitsU_CRL.push_back(0), bestMatchNOtherTrackHitsV_CRL.push_back(0);
655  bestMatchNOtherTrackHitsW_CRL.push_back(0);
656  bestMatchNOtherShowerHitsTotal_CRL.push_back(0);
657  bestMatchNOtherShowerHitsU_CRL.push_back(0);
658  bestMatchNOtherShowerHitsV_CRL.push_back(0), bestMatchNOtherShowerHitsW_CRL.push_back(0);
659  totalCRLHitsInBestMatchParentCR_CRL.push_back(0);
660  uCRLHitsInBestMatchParentCR_CRL.push_back(0);
661  vCRLHitsInBestMatchParentCR_CRL.push_back(0);
662  wCRLHitsInBestMatchParentCR_CRL.push_back(0);
663  }
664 
665  stringStream << nAboveThresholdMatches << " above threshold matches" << std::endl
666  << "Reconstruction is " << (isCorrect ? "\033[32m" : "\033[31m") << (isCorrect ? "CORRECT" : "INCORRECT")
667  << "\033[0m" << std::endl;
668 
669  if (m_visualize && useInterpretedMatching)
670  std::cout << stringStream.str() << std::endl;
671  }
672 
673  if (fillTree)
674  {
675  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "eventNumber", m_eventNumber - 1));
676  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "ID_CR", ID_CR));
677  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcE_CR", mcE_CR));
678  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPX_CR", mcPX_CR));
679  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPY_CR", mcPY_CR));
680  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPZ_CR", mcPZ_CR));
681  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "nMCHitsTotal_CR", nMCHitsTotal_CR));
682  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "nMCHitsU_CR", nMCHitsU_CR));
683  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "nMCHitsV_CR", nMCHitsV_CR));
684  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "nMCHitsW_CR", nMCHitsW_CR));
685  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcVertexX_CR", mcVertexX_CR));
686  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcVertexY_CR", mcVertexY_CR));
687  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcVertexZ_CR", mcVertexZ_CR));
688  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcEndX_CR", mcEndX_CR));
689  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcEndY_CR", mcEndY_CR));
690  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcEndZ_CR", mcEndZ_CR));
691  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "nReconstructableChildCRLs", nReconstructableChildCRLs));
692  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "nCorrectChildCRLs", nCorrectChildCRLs));
693 
694  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "ID_CRL", &ID_CRL));
695  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcE_CRL", &mcE_CRL));
696  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPX_CRL", &mcPX_CRL));
697  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPY_CRL", &mcPY_CRL));
698  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPZ_CRL", &mcPZ_CRL));
699  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "nMCHitsTotal_CRL", &nMCHitsTotal_CRL));
700  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "nMCHitsU_CRL", &nMCHitsU_CRL));
701  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "nMCHitsV_CRL", &nMCHitsV_CRL));
702  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "nMCHitsW_CRL", &nMCHitsW_CRL));
703  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcVertexX_CRL", &mcVertexX_CRL));
704  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcVertexY_CRL", &mcVertexY_CRL));
705  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcVertexZ_CRL", &mcVertexZ_CRL));
706  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcEndX_CRL", &mcEndX_CRL));
707  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcEndY_CRL", &mcEndY_CRL));
708  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcEndZ_CRL", &mcEndZ_CRL));
709  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "nAboveThresholdMatches_CRL", &nAboveThresholdMatches_CRL));
710  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "isCorrect_CRL", &isCorrect_CRL));
711  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "isCorrectParentLink_CRL", &isCorrectParentLink_CRL));
712  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchNHitsTotal_CRL", &bestMatchNHitsTotal_CRL));
713  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchNHitsU_CRL", &bestMatchNHitsU_CRL));
714  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchNHitsV_CRL", &bestMatchNHitsV_CRL));
715  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchNHitsW_CRL", &bestMatchNHitsW_CRL));
716  PANDORA_MONITORING_API(
717  SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchNSharedHitsTotal_CRL", &bestMatchNSharedHitsTotal_CRL));
718  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchNSharedHitsU_CRL", &bestMatchNSharedHitsU_CRL));
719  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchNSharedHitsV_CRL", &bestMatchNSharedHitsV_CRL));
720  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchNSharedHitsW_CRL", &bestMatchNSharedHitsW_CRL));
721  PANDORA_MONITORING_API(SetTreeVariable(
722  this->GetPandora(), m_treeName.c_str(), "bestMatchNParentTrackHitsTotal_CRL", &bestMatchNParentTrackHitsTotal_CRL));
723  PANDORA_MONITORING_API(
724  SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchNParentTrackHitsU_CRL", &bestMatchNParentTrackHitsU_CRL));
725  PANDORA_MONITORING_API(
726  SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchNParentTrackHitsV_CRL", &bestMatchNParentTrackHitsV_CRL));
727  PANDORA_MONITORING_API(
728  SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchNParentTrackHitsW_CRL", &bestMatchNParentTrackHitsW_CRL));
729  PANDORA_MONITORING_API(
730  SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchNOtherTrackHitsTotal_CRL", &bestMatchNOtherTrackHitsTotal_CRL));
731  PANDORA_MONITORING_API(
732  SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchNOtherTrackHitsU_CRL", &bestMatchNOtherTrackHitsU_CRL));
733  PANDORA_MONITORING_API(
734  SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchNOtherTrackHitsV_CRL", &bestMatchNOtherTrackHitsV_CRL));
735  PANDORA_MONITORING_API(
736  SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchNOtherTrackHitsW_CRL", &bestMatchNOtherTrackHitsW_CRL));
737  PANDORA_MONITORING_API(SetTreeVariable(
738  this->GetPandora(), m_treeName.c_str(), "bestMatchNOtherShowerHitsTotal_CRL", &bestMatchNOtherShowerHitsTotal_CRL));
739  PANDORA_MONITORING_API(
740  SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchNOtherShowerHitsU_CRL", &bestMatchNOtherShowerHitsU_CRL));
741  PANDORA_MONITORING_API(
742  SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchNOtherShowerHitsV_CRL", &bestMatchNOtherShowerHitsV_CRL));
743  PANDORA_MONITORING_API(
744  SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchNOtherShowerHitsW_CRL", &bestMatchNOtherShowerHitsW_CRL));
745  PANDORA_MONITORING_API(SetTreeVariable(
746  this->GetPandora(), m_treeName.c_str(), "totalCRLHitsInBestMatchParentCR_CRL", &totalCRLHitsInBestMatchParentCR_CRL));
747  PANDORA_MONITORING_API(
748  SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "uCRLHitsInBestMatchParentCR_CRL", &uCRLHitsInBestMatchParentCR_CRL));
749  PANDORA_MONITORING_API(
750  SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "vCRLHitsInBestMatchParentCR_CRL", &vCRLHitsInBestMatchParentCR_CRL));
751  PANDORA_MONITORING_API(
752  SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "wCRLHitsInBestMatchParentCR_CRL", &wCRLHitsInBestMatchParentCR_CRL));
753 
754  PANDORA_MONITORING_API(
755  SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchOtherShowerHitsID_CRL", &bestMatchOtherShowerHitsID_CRL));
756  PANDORA_MONITORING_API(SetTreeVariable(
757  this->GetPandora(), m_treeName.c_str(), "bestMatchOtherShowerHitsDistance_CRL", &bestMatchOtherShowerHitsDistance_CRL));
758  PANDORA_MONITORING_API(
759  SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchOtherTrackHitsID_CRL", &bestMatchOtherTrackHitsID_CRL));
760  PANDORA_MONITORING_API(SetTreeVariable(
761  this->GetPandora(), m_treeName.c_str(), "bestMatchOtherTrackHitsDistance_CRL", &bestMatchOtherTrackHitsDistance_CRL));
762  PANDORA_MONITORING_API(
763  SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchParentTrackHitsID_CRL", &bestMatchParentTrackHitsID_CRL));
764  PANDORA_MONITORING_API(SetTreeVariable(
765  this->GetPandora(), m_treeName.c_str(), "bestMatchParentTrackHitsDistance_CRL", &bestMatchParentTrackHitsDistance_CRL));
766  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchCRLHitsInCRID_CRL", &bestMatchCRLHitsInCRID_CRL));
767  PANDORA_MONITORING_API(
768  SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchCRLHitsInCRDistance_CRL", &bestMatchCRLHitsInCRDistance_CRL));
769 
770  PANDORA_MONITORING_API(FillTree(this->GetPandora(), m_treeName.c_str()));
771  }
772 
773  stringStream << "------------------------------------------------------------------------------------------------" << std::endl;
774  stringStream << nCorrectChildCRLs << " / " << nReconstructableChildCRLs << " CRLs correctly reconstructed" << std::endl;
775  stringStream << "------------------------------------------------------------------------------------------------" << std::endl;
776  stringStream << "------------------------------------------------------------------------------------------------" << std::endl;
777  }
778 
779  if (printToScreen && !(m_visualize && useInterpretedMatching))
780  {
781  std::cout << stringStream.str() << std::endl;
782  }
783 }
784 
785 //------------------------------------------------------------------------------------------------------------------------------------------
786 
787 #ifdef MONITORING
788 void MuonLeadingEventValidationAlgorithm::PrintHits(const CaloHitList caloHitList, const bool isCR) const
789 {
790  const std::string stringTag(isCR ? "MC_CR" : "MC_DR");
791 
792  for (const CaloHit *const pCaloHit : caloHitList)
793  {
794  const CartesianVector hitPosition(pCaloHit->GetPositionVector().GetX() - pCaloHit->GetX0(), pCaloHit->GetPositionVector().GetY(),
795  pCaloHit->GetPositionVector().GetZ());
796 
797  PandoraMonitoringApi::AddMarkerToVisualization(this->GetPandora(), &hitPosition, stringTag, isCR ? BLUE : RED, 2);
798  }
799 
800  PandoraMonitoringApi::ViewEvent(this->GetPandora());
801 }
802 #endif
803 
804 //------------------------------------------------------------------------------------------------------------------------------------------
805 
806 #ifdef MONITORING
807 void MuonLeadingEventValidationAlgorithm::PrintHits(const CaloHitList totalCaloHitList, const CaloHitList otherShowerCaloHitList,
808  const CaloHitList otherTrackCaloHitList, const CaloHitList parentTrackCaloHitList, const std::string &stringTag) const
809 {
810  for (const CaloHit *const pCaloHit : totalCaloHitList)
811  {
812  std::string newStringTag(stringTag);
813  const CartesianVector hitPosition(pCaloHit->GetPositionVector().GetX() - pCaloHit->GetX0(), pCaloHit->GetPositionVector().GetY(),
814  pCaloHit->GetPositionVector().GetZ());
815 
816  if (std::find(otherShowerCaloHitList.begin(), otherShowerCaloHitList.end(), pCaloHit) != otherShowerCaloHitList.end())
817  {
818  newStringTag += "_OTHER_SHOWER";
819 
820  PandoraMonitoringApi::AddMarkerToVisualization(this->GetPandora(), &hitPosition, newStringTag, VIOLET, 2);
821  }
822  else if (std::find(otherTrackCaloHitList.begin(), otherTrackCaloHitList.end(), pCaloHit) != otherTrackCaloHitList.end())
823  {
824  newStringTag += "_OTHER_TRACK";
825 
826  PandoraMonitoringApi::AddMarkerToVisualization(this->GetPandora(), &hitPosition, newStringTag, RED, 2);
827  }
828  else if (std::find(parentTrackCaloHitList.begin(), parentTrackCaloHitList.end(), pCaloHit) != parentTrackCaloHitList.end())
829  {
830  newStringTag += "_PARENT_TRACK";
831 
832  PandoraMonitoringApi::AddMarkerToVisualization(this->GetPandora(), &hitPosition, newStringTag, BLUE, 2);
833  }
834  else
835  {
836  PandoraMonitoringApi::AddMarkerToVisualization(this->GetPandora(), &hitPosition, newStringTag, BLACK, 2);
837  }
838  }
839 
840  PandoraMonitoringApi::ViewEvent(this->GetPandora());
841 }
842 #endif
843 
844 //------------------------------------------------------------------------------------------------------------------------------------------
845 
846 #ifdef MONITORING
848  const CaloHitList totalCaloHitList, const CaloHitList leadingCaloHitList, const std::string &stringTag) const
849 {
850  for (const CaloHit *const pCaloHit : totalCaloHitList)
851  {
852  std::string newStringTag(stringTag);
853  const CartesianVector hitPosition(pCaloHit->GetPositionVector().GetX() - pCaloHit->GetX0(), pCaloHit->GetPositionVector().GetY(),
854  pCaloHit->GetPositionVector().GetZ());
855 
856  if (std::find(leadingCaloHitList.begin(), leadingCaloHitList.end(), pCaloHit) != leadingCaloHitList.end())
857  {
858  newStringTag += "_LEADING";
859 
860  PandoraMonitoringApi::AddMarkerToVisualization(this->GetPandora(), &hitPosition, newStringTag, RED, 2);
861  }
862  else
863  {
864  PandoraMonitoringApi::AddMarkerToVisualization(this->GetPandora(), &hitPosition, newStringTag, DARKGREEN, 2);
865  }
866  }
867 
868  PandoraMonitoringApi::ViewEvent(this->GetPandora());
869 }
870 #endif
871 
872 //------------------------------------------------------------------------------------------------------------------------------------------
873 
875  const CaloHitList &contaminationHits, const CaloHitList &leadingMCHits, FloatVector &bestMatchContaminationHitsDistance) const
876 {
877  CaloHitList leadingU, leadingV, leadingW;
878  this->GetHitsOfType(leadingMCHits, TPC_VIEW_U, leadingU);
879  this->GetHitsOfType(leadingMCHits, TPC_VIEW_V, leadingV);
880  this->GetHitsOfType(leadingMCHits, TPC_VIEW_W, leadingW);
881 
882  for (const CaloHit *const pContaminationHit : contaminationHits)
883  {
884  const CartesianVector &hitPosition(pContaminationHit->GetPositionVector());
885 
886  if ((pContaminationHit->GetHitType() == TPC_VIEW_U) && (!leadingU.empty()))
887  bestMatchContaminationHitsDistance.push_back(LArClusterHelper::GetClosestDistance(hitPosition, leadingU));
888 
889  if ((pContaminationHit->GetHitType() == TPC_VIEW_V) && (!leadingV.empty()))
890  bestMatchContaminationHitsDistance.push_back(LArClusterHelper::GetClosestDistance(hitPosition, leadingV));
891 
892  if ((pContaminationHit->GetHitType() == TPC_VIEW_W) && (!leadingW.empty()))
893  bestMatchContaminationHitsDistance.push_back(LArClusterHelper::GetClosestDistance(hitPosition, leadingW));
894  }
895 }
896 
897 //------------------------------------------------------------------------------------------------------------------------------------------
898 
899 void MuonLeadingEventValidationAlgorithm::GetHitsOfType(const CaloHitList &inputList, const HitType hitType, CaloHitList &outputList) const
900 {
901  for (const CaloHit *const pCaloHit : inputList)
902  {
903  if (pCaloHit->GetHitType() == hitType)
904  outputList.push_back(pCaloHit);
905  }
906 }
907 
908 //------------------------------------------------------------------------------------------------------------------------------------------
909 
910 StatusCode MuonLeadingEventValidationAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
911 {
912  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
913  XmlHelper::ReadValue(xmlHandle, "MinPrimaryGoodHits", m_validationParameters.m_minPrimaryGoodHits));
914 
915  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
916  XmlHelper::ReadValue(xmlHandle, "MinHitsForGoodView", m_validationParameters.m_minHitsForGoodView));
917 
918  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
919  XmlHelper::ReadValue(xmlHandle, "MinPrimaryGoodViews", m_validationParameters.m_minPrimaryGoodViews));
920 
921  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
922  XmlHelper::ReadValue(xmlHandle, "SelectInputHits", m_validationParameters.m_selectInputHits));
923 
924  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
925  XmlHelper::ReadValue(xmlHandle, "MinHitSharingFraction", m_validationParameters.m_minHitSharingFraction));
926 
927  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
928  XmlHelper::ReadValue(xmlHandle, "MaxPhotonPropagation", m_validationParameters.m_maxPhotonPropagation));
929 
930  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
931  XmlHelper::ReadValue(xmlHandle, "FoldToPrimaries", m_validationParameters.m_foldBackHierarchy));
932 
934 
935  PANDORA_RETURN_RESULT_IF_AND_IF(
936  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadVectorOfValues(xmlHandle, "DeltaRayIDs", m_deltaRayIDs));
937 
938  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "DeltaRayMode", m_deltaRayMode));
939 
940  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MichelMode", m_michelMode));
941 
942  PANDORA_RETURN_RESULT_IF_AND_IF(
943  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "CosmicRaysToSkip", m_cosmicRaysToSkip));
944 
945  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "Visualize", m_visualize));
946 
947  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
948  XmlHelper::ReadValue(xmlHandle, "RemoveRecoCosmicRayHits", m_removeRecoCosmicRayHits));
949 
950  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
951  XmlHelper::ReadValue(xmlHandle, "IgnoreIncorrectCosmicRays", m_ignoreIncorrectCosmicRays));
952 
953  PANDORA_RETURN_RESULT_IF_AND_IF(
954  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "WriteRawMatchesToTree", m_writeRawMatchesToTree));
955 
957 }
958 
959 } // namespace lar_content
const LArMCParticleHelper::PfoContributionMap & GetPfoToHitsMap() const
Get the pfo to hits map.
unsigned int m_minPrimaryGoodViews
the minimum number of primary good views
Header file for the pfo helper class.
static void GetMuonPfoContaminationContribution(const pandora::CaloHitList &cosmicRayPfoHitList, const pandora::CaloHitList &leadingMCHitList, pandora::CaloHitList &leadingHitsInParentCosmicRay)
Determine the leading MCParticle hits within a cosmic ray pfo hit list.
bool m_removeRecoCosmicRayHits
Whether to remove the reconstructed cosmic ray hits from leading particle metrics.
void DetermineIncorrectlyReconstructedCosmicRays(const pandora::MCParticleList *const pMCParticleList, const pandora::CaloHitList *const pCaloHitList, const pandora::PfoList *const pPfoList, pandora::MCParticleList &incorrectlyReconstructedCosmicRays) const
Perform the cosmic ray matching procedure and identify incorrectly reconstructed cosmic rays...
static void SelectReconstructableLeadingParticles(const pandora::MCParticleList *pMCParticleList, const pandora::CaloHitList *pCaloHitList, const ValidationParameters &parameters, const pandora::CaloHitList &recoMuonHitList, LArMCParticleHelper::MCContributionMap &selectedMCParticlesToHitsMap)
Select target, reconstructable mc particles in the cosmic ray hierarchy.
std::unordered_map< const pandora::MCParticle *, pandora::CaloHitList > MCContributionMap
bool m_selectInputHits
whether to select input hits
const LArMCParticleHelper::MCContributionMap & GetTargetMCParticleToHitsMap() const
Get the target mc particle to hits map.
unsigned int m_minPrimaryGoodHits
the minimum number of primary good Hits
void InterpretMatching(const ValidationInfo &validationInfo, LArMCParticleHelper::MCParticleToPfoHitSharingMap &interpretedMCToPfoHitSharingMap) const
Apply an interpretative matching procedure to the comprehensive matches in the provided validation in...
static void GetPfoToReconstructable2DHitsMap(const pandora::PfoList &pfoList, const MCContributionMap &selectedMCParticleToHitsMap, PfoContributionMap &pfoToReconstructable2DHitsMap, const bool foldBackHierarchy)
Get mapping from Pfo to reconstructable 2D hits (=good hits belonging to a selected reconstructable M...
const LArMCParticleHelper::MCContributionMap & GetAllMCParticleToHitsMap() const
Get the all mc particle to hits map.
static void GetPfoMCParticleHitSharingMaps(const PfoContributionMap &pfoToReconstructable2DHitsMap, const MCContributionMapVector &selectedMCParticleToHitsMaps, PfoToMCParticleHitSharingMap &pfoToMCParticleHitSharingMap, MCParticleToPfoHitSharingMap &mcParticleToPfoHitSharingMap)
Get the mappings from Pfo -> pair (reconstructable MCparticles, number of reconstructable 2D hits sha...
void PerformUnfoldedMatching(const pandora::MCParticleList *const pMCParticleList, const pandora::CaloHitList *const pCaloHitList, const pandora::PfoList *const pPfoList, const pandora::CaloHitList &recoCosmicRayHitList, const float minHitSharingFraction, ValidationInfo &validationInfo) const
Perform the main matching procedure.
std::map< const pandora::MCParticle *, PfoToSharedHitsVector > MCParticleToPfoHitSharingMap
intermediate_table::const_iterator const_iterator
const LArMCParticleHelper::MCParticleToPfoHitSharingMap & GetMCToPfoHitSharingMap() const
Get the mc to pfo hit sharing map.
std::vector< int > m_deltaRayIDs
If filled, to contain the list leading particles to run metrics over.
void SetInterpretedMCToPfoHitSharingMap(const LArMCParticleHelper::MCParticleToPfoHitSharingMap &interpretedMCToPfoHitSharingMap)
Set the interpreted mc to pfo hit sharing map.
std::vector< int > IntVector
bool m_foldBackHierarchy
whether to fold the hierarchy back to the primary (neutrino) or leading particles (test beam) ...
void RemoveIncorrectlyReconstructedCosmicRays(const pandora::MCParticleList *const pMCParticleList, const pandora::CaloHitList *const pCaloHitList, const pandora::PfoList *const pPfoList, ValidationInfo &validationInfo) const
Remove incorrectly reconstructed cosmic rays from main matching maps.
void FillValidationInfo(const pandora::MCParticleList *const pMCParticleList, const pandora::CaloHitList *const pCaloHitList, const pandora::PfoList *const pPfoList, ValidationInfo &validationInfo) const
Fill the validation info containers.
void ProcessOutput(const ValidationInfo &validationInfo, const bool useInterpretedMatching, const bool printToScreen, const bool fillTree) const
Print matching information in a provided validation info object, and write information to tree if con...
Header file for the lar monitoring helper helper class.
void SetMCToPfoHitSharingMap(const LArMCParticleHelper::MCParticleToPfoHitSharingMap &mcToPfoHitSharingMap)
Set the mc to pfo hit sharing map.
void GetHitsOfType(const pandora::CaloHitList &inputList, const pandora::HitType hitType, pandora::CaloHitList &outputList) const
To filter out the hits of a given type from an input list.
void GetRecoCosmicRayHits(const pandora::MCParticleList *const pMCParticleList, const pandora::CaloHitList *const pCaloHitList, const pandora::PfoList *const pPfoList, pandora::CaloHitList &recoCosmicRayHitList) const
Determine all reconstructable hits in cosmic ray pfos.
unsigned int m_minHitsForGoodView
the minimum number of Hits for a good view
bool m_visualize
Whether to visualize the MC and reco leading particles.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
float m_maxPhotonPropagation
the maximum photon propagation length
int m_cosmicRaysToSkip
The number of reconstructable cosmic rays to skip.
TFile f
Definition: plotHisto.C:6
static void GetOrderedMCParticleVector(const LArMCParticleHelper::MCContributionMapVector &selectedMCParticleToGoodHitsMaps, pandora::MCParticleVector &orderedMCParticleVector)
Order input MCParticles by their number of hits.
static bool SortByMomentum(const pandora::MCParticle *const pLhs, const pandora::MCParticle *const pRhs)
Sort mc particles by their momentum.
static bool IsCosmicRay(const pandora::MCParticle *const pMCParticle)
Return true if passed a primary cosmic ray MCParticle.
void SetTargetMCParticleToHitsMap(const LArMCParticleHelper::MCContributionMap &targetMCParticleToHitsMap)
Set the target mc particle to hits map.
static bool IsMichel(const pandora::MCParticle *const pMCParticle)
Return true if input MCParticle is a child of a cosmic ray and has &#39;decay&#39; process tag...
static const pandora::ParticleFlowObject * GetParentPfo(const pandora::ParticleFlowObject *const pPfo)
Get the primary parent pfo.
Header file for the cluster helper class.
Header file for the muon leading helper class.
bool m_ignoreIncorrectCosmicRays
Whether to remove the leading particles with incorrrectly reconstructed parents from metrics...
static void GetPfoMatchContamination(const pandora::MCParticle *const pLeadingParticle, const pandora::CaloHitList &matchedPfoHitList, pandora::CaloHitList &parentTrackHits, pandora::CaloHitList &otherTrackHits, pandora::CaloHitList &otherShowerHits)
Separate a leading pfo hit list according to the true owner of the hit e.g. other shower...
void PrintHits(const pandora::CaloHitList totalCaloHitList, const pandora::CaloHitList leadingCaloHitList, const std::string &stringTag) const
Print leading MCParticle hits.
std::vector< art::Ptr< simb::MCParticle > > MCParticleVector
const LArMCParticleHelper::MCParticleToPfoHitSharingMap & GetInterpretedMCToPfoHitSharingMap() const
Get the interpreted mc to pfo hit sharing map.
float m_minHitSharingFraction
the minimum Hit sharing fraction
void SetAllMCParticleToHitsMap(const LArMCParticleHelper::MCContributionMap &allMCParticleToHitsMap)
Set the all mc particle to hits map.
void FillContaminationHitsDistance(const pandora::CaloHitList &contaminationHits, const pandora::CaloHitList &leadingMCHits, pandora::FloatVector &bestMatchContaminationHitsDistance) const
Fill an input contamination hit distance vector with the closest distance of each contaminant hit to ...
LArMuonLeadingHelper::ValidationParameters m_validationParameters
The definition of a reconstructable MCParticle.
std::pair< const pandora::ParticleFlowObject *, pandora::CaloHitList > PfoCaloHitListPair
HitType
Definition: HitType.h:12
void SetPfoToHitsMap(const LArMCParticleHelper::PfoContributionMap &pfoToHitsMap)
Set the pfo to hits map.
bool m_writeRawMatchesToTree
Whether to write all matches to output tree.
Header file for the muon leading event validation algorithm.
bool IsGoodMatch(const pandora::CaloHitList &trueHits, const pandora::CaloHitList &recoHits, const pandora::CaloHitList &sharedHits) const
Whether a provided mc primary and pfo are deemed to be a good match.
std::unordered_map< const pandora::ParticleFlowObject *, pandora::CaloHitList > PfoContributionMap
static unsigned int CountHitsByType(const pandora::HitType hitType, const pandora::CaloHitList &caloHitList)
Count the number of calo hits, in a provided list, of a specified type.
std::list< Vertex > VertexList
Definition: DCEL.h:169
std::map< const pandora::ParticleFlowObject *, MCParticleToSharedHitsVector > PfoToMCParticleHitSharingMap
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static bool IsDeltaRay(const pandora::MCParticle *const pMCParticle)
Return true if input MCParticle is a child of a cosmic ray and has &#39;delta ray&#39; process tag...
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.
vertex reconstruction