LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
NeutrinoEventValidationAlgorithm.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 
14 
16 
17 #include <sstream>
18 
19 using namespace pandora;
20 
21 namespace lar_content
22 {
23 
24 NeutrinoEventValidationAlgorithm::NeutrinoEventValidationAlgorithm() :
25  m_useTrueNeutrinosOnly(false)
26 {
27 }
28 
29 //------------------------------------------------------------------------------------------------------------------------------------------
30 
32 {
33 }
34 
35 //------------------------------------------------------------------------------------------------------------------------------------------
36 
37 void NeutrinoEventValidationAlgorithm::FillValidationInfo(const MCParticleList *const pMCParticleList,
38  const CaloHitList *const pCaloHitList, const PfoList *const pPfoList, ValidationInfo &validationInfo) const
39 {
40  if (pMCParticleList && pCaloHitList)
41  {
42  LArMCParticleHelper::MCContributionMap targetMCParticleToHitsMap;
44  pMCParticleList, pCaloHitList, m_primaryParameters, LArMCParticleHelper::IsBeamNeutrinoFinalState, targetMCParticleToHitsMap);
47  pMCParticleList, pCaloHitList, m_primaryParameters, LArMCParticleHelper::IsCosmicRay, targetMCParticleToHitsMap);
48 
50  parameters.m_minPrimaryGoodHits = 0;
51  parameters.m_minHitsForGoodView = 0;
52  parameters.m_minHitSharingFraction = 0.f;
53  LArMCParticleHelper::MCContributionMap allMCParticleToHitsMap;
55  pMCParticleList, pCaloHitList, parameters, LArMCParticleHelper::IsBeamNeutrinoFinalState, allMCParticleToHitsMap);
58  pMCParticleList, pCaloHitList, parameters, LArMCParticleHelper::IsCosmicRay, allMCParticleToHitsMap);
59 
60  validationInfo.SetTargetMCParticleToHitsMap(targetMCParticleToHitsMap);
61  validationInfo.SetAllMCParticleToHitsMap(allMCParticleToHitsMap);
62  }
63 
64  if (pPfoList)
65  {
66  PfoList allConnectedPfos;
67  LArPfoHelper::GetAllConnectedPfos(*pPfoList, allConnectedPfos);
68 
69  PfoList finalStatePfos;
70  for (const ParticleFlowObject *const pPfo : allConnectedPfos)
71  {
73  finalStatePfos.push_back(pPfo);
74  }
75 
78  finalStatePfos, validationInfo.GetAllMCParticleToHitsMap(), pfoToHitsMap, m_primaryParameters.m_foldBackHierarchy);
79 
80  validationInfo.SetPfoToHitsMap(pfoToHitsMap);
81  }
82 
86  validationInfo.GetPfoToHitsMap(), {validationInfo.GetAllMCParticleToHitsMap()}, pfoToMCHitSharingMap, mcToPfoHitSharingMap);
87 
88  // ATTN : Ensure all mc primaries have an entry in mcToPfoHitSharingMap, even if no associated pfos.
89  MCParticleVector mcPrimaryVector;
91  for (const MCParticle *pMCParticle : mcPrimaryVector)
92  {
93  if (mcToPfoHitSharingMap.find(pMCParticle) == mcToPfoHitSharingMap.end())
94  {
95  LArMCParticleHelper::PfoToSharedHitsVector pfoToSharedHitsVector;
96  mcToPfoHitSharingMap.insert(LArMCParticleHelper::MCParticleToPfoHitSharingMap::value_type(pMCParticle, pfoToSharedHitsVector));
97  }
98  }
99 
100  validationInfo.SetMCToPfoHitSharingMap(mcToPfoHitSharingMap);
101 
102  LArMCParticleHelper::MCParticleToPfoHitSharingMap interpretedMCToPfoHitSharingMap;
103  this->InterpretMatching(validationInfo, interpretedMCToPfoHitSharingMap);
104  validationInfo.SetInterpretedMCToPfoHitSharingMap(interpretedMCToPfoHitSharingMap);
105 }
106 
107 //------------------------------------------------------------------------------------------------------------------------------------------
108 
110  const ValidationInfo &validationInfo, const bool useInterpretedMatching, const bool printToScreen, const bool fillTree) const
111 {
112  if (printToScreen && useInterpretedMatching)
113  std::cout << "---INTERPRETED-MATCHING-OUTPUT------------------------------------------------------------------" << std::endl;
114  else if (printToScreen)
115  std::cout << "---RAW-MATCHING-OUTPUT--------------------------------------------------------------------------" << std::endl;
116 
117  const LArMCParticleHelper::MCParticleToPfoHitSharingMap &mcToPfoHitSharingMap(
118  useInterpretedMatching ? validationInfo.GetInterpretedMCToPfoHitSharingMap() : validationInfo.GetMCToPfoHitSharingMap());
119 
120  MCParticleVector mcPrimaryVector;
122 
123  // Neutrino Validation Bookkeeping
124  int nNeutrinoPrimaries(0);
125  for (const MCParticle *const pMCPrimary : mcPrimaryVector)
126  if (LArMCParticleHelper::IsBeamNeutrinoFinalState(pMCPrimary) && validationInfo.GetTargetMCParticleToHitsMap().count(pMCPrimary))
127  ++nNeutrinoPrimaries;
128 
129  PfoVector primaryPfoVector;
130  LArMonitoringHelper::GetOrderedPfoVector(validationInfo.GetPfoToHitsMap(), primaryPfoVector);
131 
132  int pfoIndex(0), neutrinoPfoIndex(0);
133  PfoToIdMap pfoToIdMap, neutrinoPfoToIdMap;
134 
135  for (const Pfo *const pPrimaryPfo : primaryPfoVector)
136  {
137  pfoToIdMap.insert(PfoToIdMap::value_type(pPrimaryPfo, ++pfoIndex));
138  const Pfo *const pRecoNeutrino(LArPfoHelper::IsNeutrinoFinalState(pPrimaryPfo) ? LArPfoHelper::GetParentNeutrino(pPrimaryPfo) : nullptr);
139 
140  if (pRecoNeutrino && !neutrinoPfoToIdMap.count(pRecoNeutrino))
141  neutrinoPfoToIdMap.insert(PfoToIdMap::value_type(pRecoNeutrino, ++neutrinoPfoIndex));
142  }
143 
144  LArMCParticleHelper::MCParticleIntMap triggeredToLeading, triggeredToLeadingCounter;
145 
146  PfoSet recoNeutrinos;
147  MCParticleList associatedMCPrimaries;
148 
149  int nCorrectNu(0), nTotalNu(0), nCorrectCR(0), nTotalCR(0);
150  int nFakeNu(0), nFakeCR(0), nSplitNu(0), nSplitCR(0), nLost(0), mcPrimaryIndex(0), nTargetMatches(0), nTargetNuMatches(0);
151  int nTargetCRMatches(0), nTargetGoodNuMatches(0), nTargetNuSplits(0), nTargetNuLosses(0);
152  IntVector mcPrimaryId, mcPrimaryPdg, nMCHitsTotal, nMCHitsU, nMCHitsV, nMCHitsW;
153  FloatVector mcPrimaryE, mcPrimaryPX, mcPrimaryPY, mcPrimaryPZ;
154  FloatVector mcPrimaryVtxX, mcPrimaryVtxY, mcPrimaryVtxZ, mcPrimaryEndX, mcPrimaryEndY, mcPrimaryEndZ;
155  IntVector nPrimaryMatchedPfos, nPrimaryMatchedNuPfos, nPrimaryMatchedCRPfos;
156  IntVector bestMatchPfoId, bestMatchPfoPdg, bestMatchPfoIsRecoNu, bestMatchPfoRecoNuId;
157  IntVector bestMatchPfoNHitsTotal, bestMatchPfoNHitsU, bestMatchPfoNHitsV, bestMatchPfoNHitsW;
158  IntVector bestMatchPfoNSharedHitsTotal, bestMatchPfoNSharedHitsU, bestMatchPfoNSharedHitsV, bestMatchPfoNSharedHitsW;
159 
160  std::stringstream targetSS;
161  const std::string name("Nu");
162 
163  for (const MCParticle *const pMCPrimary : mcPrimaryVector)
164  {
165  const bool hasMatch(mcToPfoHitSharingMap.count(pMCPrimary) && !mcToPfoHitSharingMap.at(pMCPrimary).empty());
166  const bool isTargetPrimary(validationInfo.GetTargetMCParticleToHitsMap().count(pMCPrimary));
167 
168  if (!isTargetPrimary && !hasMatch)
169  continue;
170 
171  associatedMCPrimaries.push_back(pMCPrimary);
172  const int nTargetPrimaries(associatedMCPrimaries.size());
173  const bool isLastNeutrinoPrimary(++mcPrimaryIndex == nNeutrinoPrimaries);
174  const CaloHitList &mcPrimaryHitList(validationInfo.GetAllMCParticleToHitsMap().at(pMCPrimary));
175 
177  const int isBeamNeutrinoFinalState(LArMCParticleHelper::IsBeamNeutrinoFinalState(pMCPrimary));
178  const int isCosmicRay(LArMCParticleHelper::IsCosmicRay(pMCPrimary));
179 #ifdef MONITORING
180  const CartesianVector &targetVertex(LArMCParticleHelper::GetParentMCParticle(pMCPrimary)->GetVertex());
181  const float targetVertexX(targetVertex.GetX()), targetVertexY(targetVertex.GetY()), targetVertexZ(targetVertex.GetZ());
182 #endif
183 
184  targetSS << (!isTargetPrimary ? "(Non target) " : "") << "PrimaryId " << mcPrimaryIndex << ", Nu " << isBeamNeutrinoFinalState
185  << ", CR " << isCosmicRay << ", MCPDG " << pMCPrimary->GetParticleId() << ", Energy " << pMCPrimary->GetEnergy()
186  << ", Dist. " << (pMCPrimary->GetEndpoint() - pMCPrimary->GetVertex()).GetMagnitude() << ", nMCHits "
187  << mcPrimaryHitList.size() << " (" << LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, mcPrimaryHitList) << ", "
188  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, mcPrimaryHitList) << ", "
189  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, mcPrimaryHitList) << ")" << std::endl;
190 
191  mcPrimaryId.push_back(mcPrimaryIndex);
192  mcPrimaryPdg.push_back(pMCPrimary->GetParticleId());
193  mcPrimaryE.push_back(pMCPrimary->GetEnergy());
194  mcPrimaryPX.push_back(pMCPrimary->GetMomentum().GetX());
195  mcPrimaryPY.push_back(pMCPrimary->GetMomentum().GetY());
196  mcPrimaryPZ.push_back(pMCPrimary->GetMomentum().GetZ());
197  mcPrimaryVtxX.push_back(pMCPrimary->GetVertex().GetX());
198  mcPrimaryVtxY.push_back(pMCPrimary->GetVertex().GetY());
199  mcPrimaryVtxZ.push_back(pMCPrimary->GetVertex().GetZ());
200  mcPrimaryEndX.push_back(pMCPrimary->GetEndpoint().GetX());
201  mcPrimaryEndY.push_back(pMCPrimary->GetEndpoint().GetY());
202  mcPrimaryEndZ.push_back(pMCPrimary->GetEndpoint().GetZ());
203  nMCHitsTotal.push_back(mcPrimaryHitList.size());
204  nMCHitsU.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, mcPrimaryHitList));
205  nMCHitsV.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, mcPrimaryHitList));
206  nMCHitsW.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, mcPrimaryHitList));
207 
208  int matchIndex(0), nPrimaryMatches(0), nPrimaryNuMatches(0), nPrimaryCRMatches(0), nPrimaryGoodNuMatches(0), nPrimaryNuSplits(0);
209 #ifdef MONITORING
210  float recoVertexX(std::numeric_limits<float>::max()), recoVertexY(std::numeric_limits<float>::max()),
211  recoVertexZ(std::numeric_limits<float>::max());
212 #endif
213  for (const LArMCParticleHelper::PfoCaloHitListPair &pfoToSharedHits : mcToPfoHitSharingMap.at(pMCPrimary))
214  {
215  const CaloHitList &sharedHitList(pfoToSharedHits.second);
216  const CaloHitList &pfoHitList(validationInfo.GetPfoToHitsMap().at(pfoToSharedHits.first));
217 
218  const bool isRecoNeutrinoFinalState(LArPfoHelper::IsNeutrinoFinalState(pfoToSharedHits.first));
219  const bool isGoodMatch(this->IsGoodMatch(mcPrimaryHitList, pfoHitList, sharedHitList));
220 
221  const int pfoId(pfoToIdMap.at(pfoToSharedHits.first));
222  const int recoNuId(isRecoNeutrinoFinalState ? neutrinoPfoToIdMap.at(LArPfoHelper::GetParentNeutrino(pfoToSharedHits.first)) : -1);
223 
224  if (0 == matchIndex++)
225  {
226  bestMatchPfoId.push_back(pfoId);
227  bestMatchPfoPdg.push_back(pfoToSharedHits.first->GetParticleId());
228  bestMatchPfoIsRecoNu.push_back(isRecoNeutrinoFinalState ? 1 : 0);
229  bestMatchPfoRecoNuId.push_back(recoNuId);
230  bestMatchPfoNHitsTotal.push_back(pfoHitList.size());
231  bestMatchPfoNHitsU.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, pfoHitList));
232  bestMatchPfoNHitsV.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, pfoHitList));
233  bestMatchPfoNHitsW.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, pfoHitList));
234  bestMatchPfoNSharedHitsTotal.push_back(sharedHitList.size());
235  bestMatchPfoNSharedHitsU.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, sharedHitList));
236  bestMatchPfoNSharedHitsV.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, sharedHitList));
237  bestMatchPfoNSharedHitsW.push_back(LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, sharedHitList));
238 #ifdef MONITORING
239  try
240  {
241  const Vertex *const pRecoVertex(LArPfoHelper::GetVertex(
242  isRecoNeutrinoFinalState ? LArPfoHelper::GetParentNeutrino(pfoToSharedHits.first) : pfoToSharedHits.first));
243  recoVertexX = pRecoVertex->GetPosition().GetX();
244  recoVertexY = pRecoVertex->GetPosition().GetY();
245  recoVertexZ = pRecoVertex->GetPosition().GetZ();
246  }
247  catch (const StatusCodeException &)
248  {
249  }
250 #endif
251  }
252 
253  if (isGoodMatch)
254  ++nPrimaryMatches;
255 
256  if (isRecoNeutrinoFinalState)
257  {
258  const Pfo *const pRecoNeutrino(LArPfoHelper::GetParentNeutrino(pfoToSharedHits.first));
259  const bool isSplitRecoNeutrino(!recoNeutrinos.empty() && !recoNeutrinos.count(pRecoNeutrino));
260  if (!isSplitRecoNeutrino && isGoodMatch)
261  ++nPrimaryGoodNuMatches;
262  if (isSplitRecoNeutrino && isBeamNeutrinoFinalState && isGoodMatch)
263  ++nPrimaryNuSplits;
264  recoNeutrinos.insert(pRecoNeutrino);
265  }
266 
267  if (isRecoNeutrinoFinalState && isGoodMatch)
268  ++nPrimaryNuMatches;
269  if (!isRecoNeutrinoFinalState && isGoodMatch)
270  ++nPrimaryCRMatches;
271 
272  targetSS << "-" << (!isGoodMatch ? "(Below threshold) " : "") << "MatchedPfoId " << pfoId << ", Nu " << isRecoNeutrinoFinalState;
273  if (isRecoNeutrinoFinalState)
274  targetSS << " [NuId: " << recoNuId << "]";
275  targetSS << ", CR " << (!isRecoNeutrinoFinalState) << ", PDG " << pfoToSharedHits.first->GetParticleId() << ", nMatchedHits "
276  << sharedHitList.size() << " (" << LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, sharedHitList) << ", "
277  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, sharedHitList) << ", "
278  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, sharedHitList) << ")"
279  << ", nPfoHits " << pfoHitList.size() << " (" << LArMonitoringHelper::CountHitsByType(TPC_VIEW_U, pfoHitList) << ", "
280  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_V, pfoHitList) << ", "
281  << LArMonitoringHelper::CountHitsByType(TPC_VIEW_W, pfoHitList) << ")" << std::endl;
282  }
283 
284  if (mcToPfoHitSharingMap.at(pMCPrimary).empty())
285  {
286  targetSS << "-No matched Pfo" << std::endl;
287  bestMatchPfoId.push_back(-1);
288  bestMatchPfoPdg.push_back(0);
289  bestMatchPfoIsRecoNu.push_back(0);
290  bestMatchPfoRecoNuId.push_back(-1);
291  bestMatchPfoNHitsTotal.push_back(0);
292  bestMatchPfoNHitsU.push_back(0);
293  bestMatchPfoNHitsV.push_back(0);
294  bestMatchPfoNHitsW.push_back(0);
295  bestMatchPfoNSharedHitsTotal.push_back(0);
296  bestMatchPfoNSharedHitsU.push_back(0);
297  bestMatchPfoNSharedHitsV.push_back(0);
298  bestMatchPfoNSharedHitsW.push_back(0);
299  }
300 
301  nPrimaryMatchedPfos.push_back(nPrimaryMatches);
302  nPrimaryMatchedNuPfos.push_back(nPrimaryNuMatches);
303  nPrimaryMatchedCRPfos.push_back(nPrimaryCRMatches);
304  nTargetMatches += nPrimaryMatches;
305  nTargetNuMatches += nPrimaryNuMatches;
306  nTargetCRMatches += nPrimaryCRMatches;
307  nTargetGoodNuMatches += nPrimaryGoodNuMatches;
308  nTargetNuSplits += nPrimaryNuSplits;
309  if (0 == nPrimaryMatches)
310  ++nTargetNuLosses;
311 
312  if (fillTree)
313  {
314  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "fileIdentifier", m_fileIdentifier));
315  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "eventNumber", m_eventNumber - 1));
316  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcNuanceCode", mcNuanceCode));
317  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "isNeutrino", isBeamNeutrinoFinalState));
318  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "isCosmicRay", isCosmicRay));
319  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "nTargetPrimaries", nTargetPrimaries));
320  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "targetVertexX", targetVertexX));
321  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "targetVertexY", targetVertexY));
322  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "targetVertexZ", targetVertexZ));
323  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "recoVertexX", recoVertexX));
324  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "recoVertexY", recoVertexY));
325  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "recoVertexZ", recoVertexZ));
326  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPrimaryId", &mcPrimaryId));
327  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPrimaryPdg", &mcPrimaryPdg));
328  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPrimaryE", &mcPrimaryE));
329  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPrimaryPX", &mcPrimaryPX));
330  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPrimaryPY", &mcPrimaryPY));
331  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPrimaryPZ", &mcPrimaryPZ));
332  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPrimaryVtxX", &mcPrimaryVtxX));
333  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPrimaryVtxY", &mcPrimaryVtxY));
334  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPrimaryVtxZ", &mcPrimaryVtxZ));
335  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPrimaryEndX", &mcPrimaryEndX));
336  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPrimaryEndY", &mcPrimaryEndY));
337  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPrimaryEndZ", &mcPrimaryEndZ));
338  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPrimaryNHitsTotal", &nMCHitsTotal));
339  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPrimaryNHitsU", &nMCHitsU));
340  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPrimaryNHitsV", &nMCHitsV));
341  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "mcPrimaryNHitsW", &nMCHitsW));
342  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "nPrimaryMatchedPfos", &nPrimaryMatchedPfos));
343  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "nPrimaryMatchedNuPfos", &nPrimaryMatchedNuPfos));
344  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "nPrimaryMatchedCRPfos", &nPrimaryMatchedCRPfos));
345  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchPfoId", &bestMatchPfoId));
346  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchPfoPdg", &bestMatchPfoPdg));
347  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchPfoIsRecoNu", &bestMatchPfoIsRecoNu));
348  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchPfoRecoNuId", &bestMatchPfoRecoNuId));
349  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchPfoNHitsTotal", &bestMatchPfoNHitsTotal));
350  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchPfoNHitsU", &bestMatchPfoNHitsU));
351  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchPfoNHitsV", &bestMatchPfoNHitsV));
352  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchPfoNHitsW", &bestMatchPfoNHitsW));
353  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchPfoNSharedHitsTotal", &bestMatchPfoNSharedHitsTotal));
354  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchPfoNSharedHitsU", &bestMatchPfoNSharedHitsU));
355  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchPfoNSharedHitsV", &bestMatchPfoNSharedHitsV));
356  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "bestMatchPfoNSharedHitsW", &bestMatchPfoNSharedHitsW));
357  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "nTargetMatches", nTargetMatches));
358  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "nTargetNuMatches", nTargetNuMatches));
359  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "nTargetCRMatches", nTargetCRMatches));
360  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "nTargetGoodNuMatches", nTargetGoodNuMatches));
361  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "nTargetNuSplits", nTargetNuSplits));
362  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "nTargetNuLosses", nTargetNuLosses));
363  }
364 
365  if (isLastNeutrinoPrimary || isCosmicRay)
366  {
368 #ifdef MONITORING
369  const int interactionTypeInt(static_cast<int>(interactionType));
370 #endif
371  // ATTN Some redundancy introduced to contributing variables
372  const int isCorrectNu(isBeamNeutrinoFinalState && (nTargetGoodNuMatches == nTargetNuMatches) &&
373  (nTargetGoodNuMatches == nTargetPrimaries) && (nTargetCRMatches == 0) && (nTargetNuSplits == 0) && (nTargetNuLosses == 0));
374  const int isCorrectCR(isCosmicRay && (nTargetNuMatches == 0) && (nTargetCRMatches == 1));
375  const int isFakeNu(isCosmicRay && (nTargetNuMatches > 0));
376  const int isFakeCR(!isCosmicRay && (nTargetCRMatches > 0));
377  const int isSplitNu(!isCosmicRay && ((nTargetNuMatches > nTargetPrimaries) || (nTargetNuSplits > 0)));
378  const int isSplitCR(isCosmicRay && (nTargetCRMatches > 1));
379  const int isLost(nTargetMatches == 0);
380 
381  std::stringstream outcomeSS;
382  outcomeSS << LArInteractionTypeHelper::ToString(interactionType) << " (Nuance " << mcNuanceCode << ", Nu "
383  << isBeamNeutrinoFinalState << ", CR " << isCosmicRay << ")" << std::endl;
384 
385  if (isLastNeutrinoPrimary)
386  ++nTotalNu;
387  if (isCosmicRay)
388  ++nTotalCR;
389  if (isCorrectNu)
390  ++nCorrectNu;
391  if (isCorrectCR)
392  ++nCorrectCR;
393  if (isFakeNu)
394  ++nFakeNu;
395  if (isFakeCR)
396  ++nFakeCR;
397  if (isSplitNu)
398  ++nSplitNu;
399  if (isSplitCR)
400  ++nSplitCR;
401  if (isLost)
402  ++nLost;
403 
404  if (isCorrectNu)
405  outcomeSS << "IsCorrectNu ";
406  if (isCorrectCR)
407  outcomeSS << "IsCorrectCR ";
408  if (isFakeNu)
409  outcomeSS << "IsFake" << name << " ";
410  if (isFakeCR)
411  outcomeSS << "IsFakeCR ";
412  if (isSplitNu)
413  outcomeSS << "isSplit" << name << " ";
414  if (isSplitCR)
415  outcomeSS << "IsSplitCR ";
416  if (isLost)
417  outcomeSS << "IsLost ";
418  if (nTargetNuMatches > 0)
419  outcomeSS << "(N" << name << "Matches: " << nTargetNuMatches << ") ";
420  if (nTargetNuLosses > 0)
421  outcomeSS << "(N" << name << "Losses: " << nTargetNuLosses << ") ";
422  if (nTargetNuSplits > 0)
423  outcomeSS << "(N" << name << "Splits: " << nTargetNuSplits << ") ";
424  if (nTargetCRMatches > 0)
425  outcomeSS << "(NCRMatches: " << nTargetCRMatches << ") ";
426  if (printToScreen)
427  std::cout << outcomeSS.str() << std::endl << targetSS.str() << std::endl;
428 
429  if (fillTree)
430  {
431  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "interactionType", interactionTypeInt));
432  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "isCorrectNu", isCorrectNu));
433  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "isCorrectCR", isCorrectCR));
434  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "isFakeNu", isFakeNu));
435  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "isFakeCR", isFakeCR));
436  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "isSplitNu", isSplitNu));
437  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "isSplitCR", isSplitCR));
438  PANDORA_MONITORING_API(SetTreeVariable(this->GetPandora(), m_treeName.c_str(), "isLost", isLost));
439  PANDORA_MONITORING_API(FillTree(this->GetPandora(), m_treeName.c_str()));
440  }
441 
442  targetSS.str(std::string());
443  targetSS.clear();
444  recoNeutrinos.clear();
445  associatedMCPrimaries.clear();
446  nTargetMatches = 0;
447  nTargetNuMatches = 0;
448  nTargetCRMatches = 0;
449  nTargetGoodNuMatches = 0;
450  nTargetNuSplits = 0;
451  nTargetNuLosses = 0;
452  mcPrimaryId.clear();
453  mcPrimaryPdg.clear();
454  nMCHitsTotal.clear();
455  nMCHitsU.clear();
456  nMCHitsV.clear();
457  nMCHitsW.clear();
458  mcPrimaryE.clear();
459  mcPrimaryPX.clear();
460  mcPrimaryPY.clear();
461  mcPrimaryPZ.clear();
462  mcPrimaryVtxX.clear();
463  mcPrimaryVtxY.clear();
464  mcPrimaryVtxZ.clear();
465  mcPrimaryEndX.clear();
466  mcPrimaryEndY.clear();
467  mcPrimaryEndZ.clear();
468  nPrimaryMatchedPfos.clear();
469  nPrimaryMatchedNuPfos.clear();
470  nPrimaryMatchedCRPfos.clear();
471  bestMatchPfoId.clear();
472  bestMatchPfoPdg.clear();
473  bestMatchPfoIsRecoNu.clear();
474  bestMatchPfoRecoNuId.clear();
475  bestMatchPfoNHitsTotal.clear();
476  bestMatchPfoNHitsU.clear();
477  bestMatchPfoNHitsV.clear();
478  bestMatchPfoNHitsW.clear();
479  bestMatchPfoNSharedHitsTotal.clear();
480  bestMatchPfoNSharedHitsU.clear();
481  bestMatchPfoNSharedHitsV.clear();
482  bestMatchPfoNSharedHitsW.clear();
483  }
484  }
485 
486  if (useInterpretedMatching)
487  {
488  std::stringstream summarySS;
489  summarySS << "---SUMMARY--------------------------------------------------------------------------------------" << std::endl;
490  if (nTotalNu > 0)
491  summarySS << "#CorrectNu: " << nCorrectNu << "/" << nTotalNu
492  << ", Fraction: " << (nTotalNu > 0 ? static_cast<float>(nCorrectNu) / static_cast<float>(nTotalNu) : 0.f) << std::endl;
493  if (nTotalCR > 0)
494  summarySS << "#CorrectCR: " << nCorrectCR << "/" << nTotalCR
495  << ", Fraction: " << (nTotalCR > 0 ? static_cast<float>(nCorrectCR) / static_cast<float>(nTotalCR) : 0.f) << std::endl;
496  if (nFakeNu > 0)
497  summarySS << "#Fake" << name << ": " << nFakeNu << " ";
498  if (nFakeCR > 0)
499  summarySS << "#FakeCR: " << nFakeCR << " ";
500  if (nSplitNu > 0)
501  summarySS << "#Split" << name << ": " << nSplitNu << " ";
502  if (nSplitCR > 0)
503  summarySS << "#SplitCR: " << nSplitCR << " ";
504  if (nLost > 0)
505  summarySS << "#Lost: " << nLost << " ";
506  if (nFakeNu || nFakeCR || nSplitNu || nSplitCR || nLost)
507  summarySS << std::endl;
508  if (printToScreen)
509  std::cout << summarySS.str();
510  }
511 
512  if (printToScreen)
513  std::cout << "------------------------------------------------------------------------------------------------" << std::endl
514  << std::endl;
515 }
516 
517 //------------------------------------------------------------------------------------------------------------------------------------------
518 
519 StatusCode NeutrinoEventValidationAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
520 {
521  PANDORA_RETURN_RESULT_IF_AND_IF(
522  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "UseTrueNeutrinosOnly", m_useTrueNeutrinosOnly));
523 
525 }
526 
527 } // namespace lar_content
const LArMCParticleHelper::PfoContributionMap & GetPfoToHitsMap() const
Get the pfo to hits map.
Header file for the pfo helper class.
Header file for the neutrino event validation algorithm.
std::unordered_map< const pandora::MCParticle *, pandora::CaloHitList > MCContributionMap
const LArMCParticleHelper::MCContributionMap & GetTargetMCParticleToHitsMap() const
Get the target mc particle to hits map.
Header file for the interaction type helper class.
unsigned int m_minPrimaryGoodHits
the minimum number of primary good Hits
static const pandora::Vertex * GetVertex(const pandora::ParticleFlowObject *const pPfo)
Get the pfo vertex.
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...
std::map< const pandora::MCParticle *, PfoToSharedHitsVector > MCParticleToPfoHitSharingMap
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.
std::vector< PfoCaloHitListPair > PfoToSharedHitsVector
const LArMCParticleHelper::MCParticleToPfoHitSharingMap & GetMCToPfoHitSharingMap() const
Get the mc to pfo hit sharing map.
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) ...
bool m_useTrueNeutrinosOnly
Whether to consider only mc particles that were neutrino induced.
Header file for the lar monitoring helper helper class.
void SetMCToPfoHitSharingMap(const LArMCParticleHelper::MCParticleToPfoHitSharingMap &mcToPfoHitSharingMap)
Set the mc to pfo hit sharing map.
static unsigned int GetNuanceCode(const pandora::MCParticle *const pMCParticle)
Get the nuance code of an MCParticle.
static InteractionType GetInteractionType(const pandora::MCParticleList &mcPrimaryList)
Get the interaction type of an event.
unsigned int m_minHitsForGoodView
the minimum number of Hits for a good view
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static void GetOrderedMCParticleVector(const LArMCParticleHelper::MCContributionMapVector &selectedMCParticleToGoodHitsMaps, pandora::MCParticleVector &orderedMCParticleVector)
Order input MCParticles by their number of hits.
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 void SelectReconstructableMCParticles(const pandora::MCParticleList *pMCParticleList, const pandora::CaloHitList *pCaloHitList, const PrimaryParameters &parameters, std::function< bool(const pandora::MCParticle *const)> fCriteria, MCContributionMap &selectedMCParticlesToHitsMap)
Select target, reconstructable mc particles that match given criteria.
std::unordered_map< const pandora::MCParticle *, int > MCParticleIntMap
LArMCParticleHelper::PrimaryParameters m_primaryParameters
The mc particle primary selection parameters.
static std::string ToString(const InteractionType interactionType)
Get a string representation of an interaction type.
std::vector< art::Ptr< simb::MCParticle > > MCParticleVector
static const pandora::MCParticle * GetParentMCParticle(const pandora::MCParticle *const pMCParticle)
Get the parent mc particle.
static void GetOrderedPfoVector(const LArMCParticleHelper::PfoContributionMap &pfoToReconstructable2DHitsMap, pandora::PfoVector &orderedPfoVector)
Order input Pfos by their number of hits.
static const pandora::ParticleFlowObject * GetParentNeutrino(const pandora::ParticleFlowObject *const pPfo)
Get primary neutrino or antineutrino.
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.
std::unordered_map< const pandora::ParticleFlowObject *, unsigned int > PfoToIdMap
std::pair< const pandora::ParticleFlowObject *, pandora::CaloHitList > PfoCaloHitListPair
static bool IsFinalState(const pandora::ParticleFlowObject *const pPfo)
Whether a pfo is a primary parent particle.
void SetPfoToHitsMap(const LArMCParticleHelper::PfoContributionMap &pfoToHitsMap)
Set the pfo to hits map.
static bool IsNeutrinoFinalState(const pandora::ParticleFlowObject *const pPfo)
Whether a pfo is a final-state particle from a neutrino (or antineutrino) interaction.
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
Definition: ModuleGraph.h:25
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 void GetAllConnectedPfos(const pandora::PfoList &inputPfoList, pandora::PfoList &outputPfoList)
Get a flat list of all pfos, recursively including all daughters and parents associated with those pf...
static bool IsBeamNeutrinoFinalState(const pandora::MCParticle *const pMCParticle)
Returns true if passed a primary neutrino final state MCParticle.
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.
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...
std::map< const pandora::ParticleFlowObject *, MCParticleToSharedHitsVector > PfoToMCParticleHitSharingMap
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)