9 #include "Pandora/AlgorithmHeaders.h" 10 #include "Pandora/PdgTable.h" 24 CosmicRayTaggingMonitoringTool::CosmicRayTaggingMonitoringTool() :
25 m_minHitsToConsiderTagging(15),
28 m_minSignificance(0.1)
36 if (this->GetPandora().GetSettings()->ShouldDisplayAlgorithmInfo())
37 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
39 const MCParticleList *pMCParticleList =
nullptr;
40 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*pAlgorithm, pMCParticleList));
42 const CaloHitList *pCaloHitList =
nullptr;
43 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*pAlgorithm,
m_caloHitList2D, pCaloHitList));
59 {nuMCParticlesToGoodHitsMap, beamMCParticlesToGoodHitsMap, crMCParticlesToGoodHitsMap});
68 pfoToReconstructable2DHitsMap, mcParticlesToGoodHitsMaps, pfoToMCParticleHitSharingMap, mcParticleToPfoHitSharingMap);
75 this->
CalculatePfoMetrics(pfoToMCParticleHitSharingMap, pfoToReconstructable2DHitsMap, targetsToGoodHitsMaps, pfoSignificanceMap,
76 pfoPurityMap, pfoClassificationMap);
94 std::cout <<
"Columns with headers [n] are the number of shared hits between the Pfo and the target MCParticle with ID n." << std::endl;
96 PfoVector orderedPfoVector;
98 this->
PrintPfoTable(orderedPfoVector, pfoToReconstructable2DHitsMap, pfoPurityMap, pfoSignificanceMap, pfoClassificationMap, ambiguousPfos);
107 PfoVector sortedPfos;
108 for (
const auto &mapEntry : hitSharingMap)
109 sortedPfos.push_back(mapEntry.first);
112 for (
const ParticleFlowObject *
const pPfo : sortedPfos)
114 if (pfoToCaloHitListMap.find(pPfo) == pfoToCaloHitListMap.end())
115 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
117 const unsigned int n2DHits(pfoToCaloHitListMap.at(pPfo).size());
118 float significance(0);
126 bool foundTarget(
false);
127 unsigned int nMCHits(std::numeric_limits<unsigned int>::max());
132 if (mcContributionMap.find(targetHitsShared.first) != mcContributionMap.end())
135 nMCHits = mcContributionMap.at(targetHitsShared.first).size();
143 significance +=
static_cast<float>(targetHitsShared.second.size()) / static_cast<float>(nMCHits);
144 purity +=
static_cast<float>(targetHitsShared.second.size()) / static_cast<float>(n2DHits);
148 if (!pfoSignificanceMap.insert(PfoToFloatMap::value_type(pPfo, significance)).second)
149 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
151 if (!pfoPurityMap.insert(PfoToFloatMap::value_type(pPfo, purity)).second)
152 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
155 if (!pfoClassificationMap.insert(PfoClassificationMap::value_type(pPfo, classification)).second)
156 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
169 catch (
const StatusCodeException &)
179 const unsigned int &nHits,
const float &significance,
const float &purity,
const bool isMuon)
const 188 if (!isPure && !isImpure)
191 if (isPure && isSignificant)
194 if (isPure && !isSignificant)
197 if (!isPure && isSignificant)
200 if (!isPure && !isSignificant && isMuon)
213 if (orderedPfoVector.empty())
215 std::cout <<
"No Pfos supplied." << std::endl;
220 {
"ID",
"PID",
"",
"nHits",
"U",
"V",
"W",
"",
"nGoodHits",
"U",
"V",
"W",
"",
"Purity",
"Significance",
"Classification",
"",
"Tagged?"});
222 for (
unsigned int id = 0;
id < orderedPfoVector.size(); ++id)
224 const ParticleFlowObject *
const pPfo(orderedPfoVector.at(
id));
227 if (pfoToReconstructable2DHitsMap.end() == it)
228 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
230 if (pfoPurityMap.end() == pfoPurityMap.find(pPfo))
231 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
233 if (pfoSignificanceMap.end() == pfoSignificanceMap.find(pPfo))
234 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
236 if (pfoClassificationMap.end() == pfoClassificationMap.find(pPfo))
237 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
239 table.AddElement(
id);
240 table.AddElement(pPfo->GetParticleId());
242 CaloHitList all2DCaloHits;
247 table.AddElement(all2DCaloHits.size());
252 table.AddElement(it->second.size());
257 table.AddElement(pfoPurityMap.at(pPfo));
258 table.AddElement(pfoSignificanceMap.at(pPfo));
260 const Classification classification(pfoClassificationMap.at(pPfo));
263 const bool isTagged(std::find(ambiguousPfos.begin(), ambiguousPfos.end(), pPfo) == ambiguousPfos.end());
264 const bool isGoodTag(isTagged && (classification ==
CR_MUON || classification ==
CR_OTHER));
265 const bool isBadTag(isTagged && (classification ==
TARGET));
278 switch (classification)
301 switch (classification)
318 return "UNCLASSIFIED";
326 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"CaloHitList2D",
m_caloHitList2D));
328 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
331 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
334 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
337 PANDORA_RETURN_RESULT_IF_AND_IF(
340 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
343 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
346 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
349 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinPurity",
m_minPurity));
351 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinImpurity",
m_minImpurity));
353 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinSignificance",
m_minSignificance));
355 return STATUS_CODE_SUCCESS;
void CalculatePfoMetrics(const LArMCParticleHelper::PfoToMCParticleHitSharingMap &hitSharingMap, const LArMCParticleHelper::PfoContributionMap &pfoToCaloHitListMap, const LArMCParticleHelper::MCContributionMapVector &targetsToGoodHitsMaps, PfoToFloatMap &pfoSignificanceMap, PfoToFloatMap &pfoPurityMap, PfoClassificationMap &pfoClassificationMap) const
Calculate metrics to classify Pfos based on the target reconstructable MCParticles with which they sh...
Classification ClassifyPfo(const unsigned int &nHits, const float &significance, const float &purity, const bool isMuon) const
Classify a pfo given some metrics.
unsigned int m_minPrimaryGoodViews
the minimum number of primary good views
static bool SortByNHits(const pandora::ParticleFlowObject *const pLhs, const pandora::ParticleFlowObject *const pRhs)
Sort pfos by number of constituent hits.
Header file for the pfo helper class.
LArFormattingHelper::Color GetClassificationColor(const Classification &classification) const
Returns a unique color for each possible Pfo classification.
std::unordered_map< const pandora::MCParticle *, pandora::CaloHitList > MCContributionMap
bool m_selectInputHits
whether to select input hits
std::pair< const pandora::MCParticle *, pandora::CaloHitList > MCParticleCaloHitListPair
static void PrintMCParticleTable(const LArMCParticleHelper::MCContributionMap &selectedMCParticleToGoodHitsMaps, const pandora::MCParticleVector &orderedMCParticleVector)
Print details of selected MCParticles to the terminal in a table.
std::string m_caloHitList2D
The 2D calo hit list.
Header file for the lar calo hit class.
unsigned int m_minPrimaryGoodHits
the minimum number of primary good Hits
void FindAmbiguousPfos(const pandora::PfoList &parentCosmicRayPfos, pandora::PfoList &ambiguousPfos, const MasterAlgorithm *const pAlgorithm)
Find the list of ambiguous pfos (could represent cosmic-ray muons or neutrinos)
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...
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
bool m_foldBackHierarchy
whether to fold the hierarchy back to the primary (neutrino) or leading particles (test beam) ...
LArMCParticleHelper::PrimaryParameters m_parameters
Parameters used to decide when an MCParticle is reconstructable.
std::string GetClassificationName(const Classification &classification) const
Returns a string for each classification.
Header file for the lar monitoring helper helper class.
unsigned int m_minHitsForGoodView
the minimum number of Hits for a good view
float m_maxPhotonPropagation
the maximum photon propagation length
Color
Style code enumeration.
std::map< const pandora::ParticleFlowObject *, float > PfoToFloatMap
std::map< const pandora::ParticleFlowObject *, Classification > PfoClassificationMap
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.
static void SelectReconstructableMCParticles(const pandora::MCParticleList *pMCParticleList, const pandora::CaloHitList *pCaloHitList, const PrimaryParameters ¶meters, std::function< bool(const pandora::MCParticle *const)> fCriteria, MCContributionMap &selectedMCParticlesToHitsMap)
Select target, reconstructable mc particles that match given criteria.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read settings.
static bool IsBeamParticle(const pandora::MCParticle *const pMCParticle)
Returns true if passed a primary beam MCParticle.
unsigned int m_minHitsToConsiderTagging
The minimum number of hits to consider a Pfo for tagging.
static void PrintHeader(const std::string &title="", const unsigned int width=140)
Print a header line of a given width.
std::vector< art::Ptr< simb::MCParticle > > MCParticleVector
static void GetOrderedPfoVector(const LArMCParticleHelper::PfoContributionMap &pfoToReconstructable2DHitsMap, pandora::PfoVector &orderedPfoVector)
Order input Pfos by their number of hits.
float m_minHitSharingFraction
the minimum Hit sharing fraction
float m_minSignificance
The minimum significance to consider a Pfo as "significant".
std::vector< MCContributionMap > MCContributionMapVector
float m_minImpurity
The minimum impurity to consider a Pfo as "impure".
float m_minPurity
The minimum purity to consider a Pfo as "pure".
std::unordered_map< const pandora::ParticleFlowObject *, pandora::CaloHitList > PfoContributionMap
static void GetCaloHits(const pandora::PfoList &pfoList, const pandora::HitType &hitType, pandora::CaloHitList &caloHitList)
Get a list of calo hits of a particular hit type from a list of pfos.
bool IsMainMCParticleMuon(const pandora::ParticleFlowObject *const pPfo) const
Returns true if the main MCParticle of the supplied Pfo is a muon.
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.
std::map< const pandora::ParticleFlowObject *, MCParticleToSharedHitsVector > PfoToMCParticleHitSharingMap
void PrintPfoTable(const pandora::PfoVector &orderedPfoVector, const LArMCParticleHelper::PfoContributionMap &pfoToReconstructable2DHitsMap, const PfoToFloatMap &pfoPurityMap, const PfoToFloatMap &pfoSignificanceMap, const PfoClassificationMap &pfoClassificationMap, const pandora::PfoList &ambiguousPfos) const
Prints a table detailing all input Pfos and their classifications.