Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
EventValidationBaseAlgorithm.cc
Go to the documentation of this file.
1
10
14
16
17#include <sstream>
18
19using namespace pandora;
20
21namespace lar_content
22{
23
25 m_fileIdentifier(0),
26 m_eventNumber(0),
27 m_printAllToScreen(false),
28 m_printMatchingToScreen(true),
29 m_writeToTree(false),
30 m_useSmallPrimaries(true),
31 m_matchingMinSharedHits(5),
32 m_matchingMinCompleteness(0.1f),
33 m_matchingMinPurity(0.5f)
34{
35}
36
37//------------------------------------------------------------------------------------------------------------------------------------------
38
40{
41 if (m_writeToTree)
42 {
43 try
44 {
45 PANDORA_MONITORING_API(SaveTree(this->GetPandora(), m_treeName.c_str(), m_fileName.c_str(), "UPDATE"));
46 }
47 catch (const StatusCodeException &)
48 {
49 std::cout << "EventValidationBaseAlgorithm: Unable to write tree " << m_treeName << " to file " << m_fileName << std::endl;
50 }
51 }
52}
53
54//------------------------------------------------------------------------------------------------------------------------------------------
55
57{
59
60 const MCParticleList *pMCParticleList = nullptr;
61 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_mcParticleListName, pMCParticleList));
62
63 const CaloHitList *pCaloHitList = nullptr;
64 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_caloHitListName, pCaloHitList));
65
66 const PfoList *pPfoList = nullptr;
67 (void)PandoraContentApi::GetList(*this, m_pfoListName, pPfoList);
68
69 ValidationInfo validationInfo;
70 this->FillValidationInfo(pMCParticleList, pCaloHitList, pPfoList, validationInfo);
71
73 this->PrintAllMatches(validationInfo);
74
76 this->PrintInterpretedMatches(validationInfo);
77
78 if (m_writeToTree)
79 this->WriteInterpretedMatches(validationInfo);
80
81 return STATUS_CODE_SUCCESS;
82}
83
84//------------------------------------------------------------------------------------------------------------------------------------------
85
87 const ValidationInfo &validationInfo, LArMCParticleHelper::MCParticleToPfoHitSharingMap &interpretedMCToPfoHitSharingMap) const
88{
89 MCParticleVector mcPrimaryVector;
91
92 PfoSet usedPfos;
93 while (this->GetStrongestPfoMatch(validationInfo, mcPrimaryVector, usedPfos, interpretedMCToPfoHitSharingMap))
94 {
95 }
96 this->GetRemainingPfoMatches(validationInfo, mcPrimaryVector, usedPfos, interpretedMCToPfoHitSharingMap);
97
98 // Ensure all primaries have an entry, and sorting is as desired
99 for (const MCParticle *const pMCPrimary : mcPrimaryVector)
100 {
101 LArMCParticleHelper::PfoToSharedHitsVector &pfoHitPairs(interpretedMCToPfoHitSharingMap[pMCPrimary]);
102 std::sort(pfoHitPairs.begin(), pfoHitPairs.end(),
104 return ((a.second.size() != b.second.size()) ? a.second.size() > b.second.size() : LArPfoHelper::SortByNHits(a.first, b.first));
105 });
106 }
107}
108
109//------------------------------------------------------------------------------------------------------------------------------------------
110
112 PfoSet &usedPfos, LArMCParticleHelper::MCParticleToPfoHitSharingMap &interpretedMCToPfoHitSharingMap) const
113{
114 const MCParticle *pBestMCParticle(nullptr);
115 LArMCParticleHelper::PfoCaloHitListPair bestPfoHitPair(nullptr, CaloHitList());
116
117 for (const MCParticle *const pMCPrimary : mcPrimaryVector)
118 {
119 if (interpretedMCToPfoHitSharingMap.count(pMCPrimary))
120 continue;
121
122 if (!m_useSmallPrimaries && !validationInfo.GetTargetMCParticleToHitsMap().count(pMCPrimary))
123 continue;
124
125 if (!validationInfo.GetMCToPfoHitSharingMap().count(pMCPrimary))
126 continue;
127
128 for (const LArMCParticleHelper::PfoCaloHitListPair &pfoToSharedHits : validationInfo.GetMCToPfoHitSharingMap().at(pMCPrimary))
129 {
130 if (usedPfos.count(pfoToSharedHits.first))
131 continue;
132
133 if (!this->IsGoodMatch(validationInfo.GetAllMCParticleToHitsMap().at(pMCPrimary),
134 validationInfo.GetPfoToHitsMap().at(pfoToSharedHits.first), pfoToSharedHits.second))
135 continue;
136
137 if (pfoToSharedHits.second.size() > bestPfoHitPair.second.size())
138 {
139 pBestMCParticle = pMCPrimary;
140 bestPfoHitPair = pfoToSharedHits;
141 }
142 }
143 }
144
145 if (!pBestMCParticle || !bestPfoHitPair.first)
146 return false;
147
148 interpretedMCToPfoHitSharingMap[pBestMCParticle].push_back(bestPfoHitPair);
149 usedPfos.insert(bestPfoHitPair.first);
150 return true;
151}
152
153//------------------------------------------------------------------------------------------------------------------------------------------
154
156 const PfoSet &usedPfos, LArMCParticleHelper::MCParticleToPfoHitSharingMap &interpretedMCToPfoHitSharingMap) const
157{
158 LArMCParticleHelper::PfoToMCParticleHitSharingMap pfoToMCParticleHitSharingMap;
159
160 for (const MCParticle *const pMCPrimary : mcPrimaryVector)
161 {
162 if (!m_useSmallPrimaries && !validationInfo.GetTargetMCParticleToHitsMap().count(pMCPrimary))
163 continue;
164
165 if (!validationInfo.GetMCToPfoHitSharingMap().count(pMCPrimary))
166 continue;
167
168 for (const LArMCParticleHelper::PfoCaloHitListPair &pfoToSharedHits : validationInfo.GetMCToPfoHitSharingMap().at(pMCPrimary))
169 {
170 if (usedPfos.count(pfoToSharedHits.first))
171 continue;
172
173 const LArMCParticleHelper::MCParticleCaloHitListPair mcParticleToHits(pMCPrimary, pfoToSharedHits.second);
174 LArMCParticleHelper::PfoToMCParticleHitSharingMap::iterator iter(pfoToMCParticleHitSharingMap.find(pfoToSharedHits.first));
175
176 if (pfoToMCParticleHitSharingMap.end() == iter)
177 {
178 pfoToMCParticleHitSharingMap[pfoToSharedHits.first].push_back(mcParticleToHits);
179 }
180 else
181 {
182 if (1 != iter->second.size())
183 throw StatusCodeException(STATUS_CODE_FAILURE);
184
185 LArMCParticleHelper::MCParticleCaloHitListPair &originalMCParticleToHits(iter->second.at(0));
186
187 if (mcParticleToHits.second.size() > originalMCParticleToHits.second.size())
188 originalMCParticleToHits = mcParticleToHits;
189 }
190 }
191 }
192
193 for (const auto &mapEntry : pfoToMCParticleHitSharingMap)
194 {
195 const LArMCParticleHelper::MCParticleCaloHitListPair &mcParticleToHits(mapEntry.second.at(0));
196 interpretedMCToPfoHitSharingMap[mcParticleToHits.first].push_back(
197 LArMCParticleHelper::PfoCaloHitListPair(mapEntry.first, mcParticleToHits.second));
198 }
199}
200
201//------------------------------------------------------------------------------------------------------------------------------------------
202
203bool EventValidationBaseAlgorithm::IsGoodMatch(const CaloHitList &trueHits, const CaloHitList &recoHits, const CaloHitList &sharedHits) const
204{
205 const float purity((recoHits.size() > 0) ? static_cast<float>(sharedHits.size()) / static_cast<float>(recoHits.size()) : 0.f);
206 const float completeness((trueHits.size() > 0) ? static_cast<float>(sharedHits.size()) / static_cast<float>(trueHits.size()) : 0.f);
207
208 return ((sharedHits.size() >= m_matchingMinSharedHits) && (purity >= m_matchingMinPurity) && (completeness >= m_matchingMinCompleteness));
209}
210
211//------------------------------------------------------------------------------------------------------------------------------------------
212
214{
215 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "CaloHitListName", m_caloHitListName));
216 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "MCParticleListName", m_mcParticleListName));
217 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "PfoListName", m_pfoListName));
218
219 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
220 XmlHelper::ReadValue(xmlHandle, "MinPrimaryGoodHits", m_primaryParameters.m_minPrimaryGoodHits));
221
222 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
223 XmlHelper::ReadValue(xmlHandle, "MinHitsForGoodView", m_primaryParameters.m_minHitsForGoodView));
224
225 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
226 XmlHelper::ReadValue(xmlHandle, "MinPrimaryGoodViews", m_primaryParameters.m_minPrimaryGoodViews));
227
228 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
229 XmlHelper::ReadValue(xmlHandle, "SelectInputHits", m_primaryParameters.m_selectInputHits));
230
231 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
232 XmlHelper::ReadValue(xmlHandle, "MinHitSharingFraction", m_primaryParameters.m_minHitSharingFraction));
233
234 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
235 XmlHelper::ReadValue(xmlHandle, "MaxPhotonPropagation", m_primaryParameters.m_maxPhotonPropagation));
236
237 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
238 XmlHelper::ReadValue(xmlHandle, "FoldToPrimaries", m_primaryParameters.m_foldBackHierarchy));
239
241 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "PrintAllToScreen", m_printAllToScreen));
242
244 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "PrintMatchingToScreen", m_printMatchingToScreen));
245
246 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "WriteToTree", m_writeToTree));
247
249 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "UseSmallPrimaries", m_useSmallPrimaries));
250
252 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MatchingMinSharedHits", m_matchingMinSharedHits));
253
254 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
255 XmlHelper::ReadValue(xmlHandle, "MatchingMinCompleteness", m_matchingMinCompleteness));
256
258 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MatchingMinPurity", m_matchingMinPurity));
259
260 if (m_writeToTree)
261 {
262 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "OutputTree", m_treeName));
263 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "OutputFile", m_fileName));
264
266 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "FileIdentifier", m_fileIdentifier));
267 }
268
269 return STATUS_CODE_SUCCESS;
270}
271
272} // namespace lar_content
Grouping of header files for many classes of use in particle flow algorithms.
#define PANDORA_MONITORING_API(command)
Header file for the event validation algorithm.
Header file for the interaction type helper class.
Header file for the lar monitoring helper helper class.
Header file for the pfo helper class.
#define PANDORA_RETURN_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
Definition StatusCodes.h:31
#define PANDORA_RETURN_RESULT_IF(StatusCode1, Operator, Command)
Definition StatusCodes.h:19
static pandora::StatusCode GetList(const pandora::Algorithm &algorithm, const std::string &listName, const T *&pT)
Get a named list.
const LArMCParticleHelper::MCParticleToPfoHitSharingMap & GetMCToPfoHitSharingMap() const
Get the mc to pfo hit sharing map.
const LArMCParticleHelper::MCContributionMap & GetTargetMCParticleToHitsMap() const
Get the target mc particle to hits map.
const LArMCParticleHelper::MCContributionMap & GetAllMCParticleToHitsMap() const
Get the all mc particle to hits map.
const LArMCParticleHelper::PfoContributionMap & GetPfoToHitsMap() const
Get the pfo to hits map.
unsigned int m_matchingMinSharedHits
The minimum number of shared hits used in matching scheme.
bool m_useSmallPrimaries
Whether to consider matches to mc primaries with fewer than m_matchingMinPrimaryHits.
void PrintInterpretedMatches(const ValidationInfo &validationInfo) const
Print interpreted matching information to screen.
void InterpretMatching(const ValidationInfo &validationInfo, LArMCParticleHelper::MCParticleToPfoHitSharingMap &interpretedMCToPfoHitSharingMap) const
Apply an interpretative matching procedure to the comprehensive matches in the provided validation in...
bool m_printAllToScreen
Whether to print all/raw matching details to screen.
bool GetStrongestPfoMatch(const ValidationInfo &validationInfo, const pandora::MCParticleVector &mcPrimaryVector, pandora::PfoSet &usedPfos, LArMCParticleHelper::MCParticleToPfoHitSharingMap &interpretedMCToPfoHitSharingMap) const
Get the strongest pfo match (most matched hits) between an available mc primary and an available pfo.
void WriteInterpretedMatches(const ValidationInfo &validationInfo) const
Write interpreted matching information to tree.
virtual void FillValidationInfo(const pandora::MCParticleList *const pMCParticleList, const pandora::CaloHitList *const pCaloHitList, const pandora::PfoList *const pPfoList, ValidationInfo &validationInfo) const =0
Fill the validation info containers.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
bool m_writeToTree
Whether to write all/raw matching details to tree.
bool m_printMatchingToScreen
Whether to print matching output to screen.
float m_matchingMinCompleteness
The minimum particle completeness to declare a match.
LArMCParticleHelper::PrimaryParameters m_primaryParameters
The mc particle primary selection parameters.
void GetRemainingPfoMatches(const ValidationInfo &validationInfo, const pandora::MCParticleVector &mcPrimaryVector, const pandora::PfoSet &usedPfos, LArMCParticleHelper::MCParticleToPfoHitSharingMap &interpretedMCToPfoHitSharingMap) const
Get the best matches for any pfos left-over after the strong matching procedure.
void PrintAllMatches(const ValidationInfo &validationInfo) const
Print all/raw matching information to screen.
std::string m_caloHitListName
Name of input calo hit list.
float m_matchingMinPurity
The minimum particle purity to declare a match.
std::string m_mcParticleListName
Name of input MC particle list.
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.
pandora::StatusCode Run()
Run the algorithm.
bool m_foldBackHierarchy
whether to fold the hierarchy back to the primary (neutrino) or leading particles (test beam)
float m_minHitSharingFraction
the minimum Hit sharing fraction
float m_maxPhotonPropagation
the maximum photon propagation length
unsigned int m_minPrimaryGoodHits
the minimum number of primary good Hits
unsigned int m_minPrimaryGoodViews
the minimum number of primary good views
unsigned int m_minHitsForGoodView
the minimum number of Hits for a good view
std::map< const pandora::ParticleFlowObject *, MCParticleToSharedHitsVector > PfoToMCParticleHitSharingMap
std::vector< PfoCaloHitListPair > PfoToSharedHitsVector
std::pair< const pandora::ParticleFlowObject *, pandora::CaloHitList > PfoCaloHitListPair
std::map< const pandora::MCParticle *, PfoToSharedHitsVector > MCParticleToPfoHitSharingMap
std::pair< const pandora::MCParticle *, pandora::CaloHitList > MCParticleCaloHitListPair
static void GetOrderedMCParticleVector(const LArMCParticleHelper::MCContributionMapVector &selectedMCParticleToGoodHitsMaps, pandora::MCParticleVector &orderedMCParticleVector)
Order input MCParticles by their number of hits.
MCParticle class.
Definition MCParticle.h:26
const Pandora & GetPandora() const
Get the associated pandora instance.
Definition Process.h:116
StatusCodeException class.
static StatusCode ReadValue(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, T &t)
Read a value from an xml element.
Definition XmlHelper.h:136
MANAGED_CONTAINER< const MCParticle * > MCParticleList
std::unordered_set< const ParticleFlowObject * > PfoSet
MANAGED_CONTAINER< const CaloHit * > CaloHitList
std::vector< const MCParticle * > MCParticleVector
StatusCode
The StatusCode enum.
MANAGED_CONTAINER< const ParticleFlowObject * > PfoList