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));
 
  226         LArMCParticleHelper::PfoContributionMap::const_iterator it = pfoToReconstructable2DHitsMap.find(pPfo);
 
  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);
 
  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 
void AddElement(const T &value, const Style style=REGULAR, const Color color=DEFAULT)
Add an element to the table into the next (non-separator) column. 
float m_minSignificance
The minimum significance to consider a Pfo as "significant". 
std::vector< MCContributionMap > MCContributionMapVector
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
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. 
BEGIN_PROLOG could also be cout
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.