8 #include "art/Framework/Core/ModuleMacros.h" 
    9 #include "art/Framework/Core/EDAnalyzer.h" 
  320 #include "art/Framework/Principal/Event.h" 
  322 #include "fhiclcpp/ParameterSet.h" 
  324 #include "nusimdata/SimulationBase/MCParticle.h" 
  325 #include "nusimdata/SimulationBase/MCTruth.h" 
  333 namespace lar_pandora
 
  337     art::EDAnalyzer(pset)
 
  352     m_particleLabel = pset.get<std::string>(
"PFParticleModule", 
"pandoraNu");
 
  397     if (hitsToMCParticles.empty())
 
  400             throw cet::exception(
"LArPandora") << 
" PFParticleValidation::analyze - no sim channels found, backtracker module must be set in FHiCL " << std::endl;
 
  410     this->
GetSimpleMCPrimaryList(evt, mcParticlesToHits, hitsToMCParticles, mcParticleMatchingMap, simpleMCPrimaryList);
 
  413     this->
GetMCPrimaryMatchingMap(simpleMCPrimaryList, mcParticleMatchingMap, pfParticlesToHits, mcPrimaryMatchingMap);
 
  422         this->
PrintAllOutput(mcTruthVector, recoNeutrinoVector, mcPrimaryMatchingMap);
 
  438     for (
const MCParticlesToHits::value_type &mcParticleToHitsEntry : mcParticlesToHits)
 
  440         if (!mcParticleToHitsEntry.second.empty())
 
  441             (
void) mcParticleMatchingMap.insert(MCParticleMatchingMap::value_type(mcParticleToHitsEntry.first, 
PFParticleToMatchedHits()));
 
  445     for (
const PFParticlesToHits::value_type &recoParticleToHits : pfParticlesToHits)
 
  447         const art::Ptr<recob::PFParticle> pRecoParticle(recoParticleToHits.first);
 
  448         const HitVector &hitVector(recoParticleToHits.second);
 
  450         for (
const art::Ptr<recob::Hit> pHit : hitVector)
 
  452             HitsToMCParticles::const_iterator mcParticleIter = hitsToMCParticles.find(pHit);
 
  454             if (hitsToMCParticles.end() == mcParticleIter)
 
  457             const art::Ptr<simb::MCParticle> pTrueParticle = mcParticleIter->second;
 
  458             mcParticleMatchingMap[pTrueParticle][pRecoParticle].push_back(pHit);
 
  472     for (
const MCParticlesToHits::value_type &mapEntry : mcParticlesToHits)
 
  474         const art::Ptr<simb::MCParticle> pMCPrimary(mapEntry.first);
 
  481         simpleMCPrimary.
m_pAddress = pMCPrimary.get();
 
  482         simpleMCPrimary.
m_pdgCode = pMCPrimary->PdgCode();
 
  483         simpleMCPrimary.
m_energy = pMCPrimary->E();
 
  485         MCParticlesToHits::const_iterator trueHitsIter = mcParticlesToHits.find(pMCPrimary);
 
  487         if (mcParticlesToHits.end() != trueHitsIter)
 
  489             const HitVector &hitVector(trueHitsIter->second);
 
  496         MCParticleMatchingMap::const_iterator matchedPfoIter = mcParticleMatchingMap.find(pMCPrimary);
 
  498         if (mcParticleMatchingMap.end() != matchedPfoIter)
 
  501         simpleMCPrimaryList.push_back(simpleMCPrimary);
 
  508         simpleMCPrimary.m_id = mcPrimaryId++;
 
  515     MCParticlesToMCTruth::const_iterator iter = artMCParticlesToMCTruth.find(pMCParticle);
 
  517     if (artMCParticlesToMCTruth.end() == iter)
 
  520     const art::Ptr<simb::MCTruth> pMCTruth = iter->second;
 
  521     return (simb::kBeamNeutrino == pMCTruth->Origin());
 
  532         MCParticleMatchingMap::const_iterator matchedPfoIter = mcParticleMatchingMap.end();
 
  535         for (MCParticleMatchingMap::const_iterator iter = mcParticleMatchingMap.begin(), iterEnd = mcParticleMatchingMap.end(); iter != iterEnd; ++iter)
 
  537             if (simpleMCPrimary.m_pAddress == iter->first.get())
 
  539                 matchedPfoIter = iter;
 
  544         if (mcParticleMatchingMap.end() != matchedPfoIter)
 
  546             for (
const PFParticleToMatchedHits::value_type &contribution : matchedPfoIter->second)
 
  548                 const art::Ptr<recob::PFParticle> pMatchedPfo(contribution.first);
 
  549                 const HitVector &matchedHitVector(contribution.second);
 
  552                 simpleMatchedPfo.
m_pAddress = pMatchedPfo.get();
 
  553                 simpleMatchedPfo.
m_id = pMatchedPfo->Self();
 
  556                 PFParticlesToHits::const_iterator parentPfoIter = pfParticlesToHits.end();
 
  559                 for (PFParticlesToHits::const_iterator iter = pfParticlesToHits.begin(), iterEnd = pfParticlesToHits.end(); iter != iterEnd; ++iter)
 
  561                     if (pMatchedPfo->Parent() == iter->first->Self())
 
  563                         parentPfoIter = iter;
 
  569                     simpleMatchedPfo.
m_parentId = parentPfoIter->first->Self();
 
  571                 simpleMatchedPfo.
m_pdgCode = pMatchedPfo->PdgCode();
 
  577                 PFParticlesToHits::const_iterator pfoHitsIter = pfParticlesToHits.find(pMatchedPfo);
 
  579                 if (pfParticlesToHits.end() == pfoHitsIter)
 
  580                     throw cet::exception(
"LArPandora") << 
" PFParticleValidation::analyze --- Presence of PFParticle in map mandatory.";
 
  582                 const HitVector &pfoHitVector(pfoHitsIter->second);
 
  589                 simpleMatchedPfoList.push_back(simpleMatchedPfo);
 
  596         if (!mcPrimaryMatchingMap.insert(MCPrimaryMatchingMap::value_type(simpleMCPrimary, simpleMatchedPfoList)).second)
 
  597             throw cet::exception(
"LArPandora") << 
" PFParticleValidation::analyze --- Double-counting MC primaries.";
 
  609     for (
const auto &mapEntry : artMCTruthToMCParticles)
 
  611         const art::Ptr<simb::MCTruth> truth = mapEntry.first;
 
  613         if (!truth->NeutrinoSet())
 
  616         if (mcTruthVector.end() == std::find(mcTruthVector.begin(), mcTruthVector.end(), truth))
 
  617             mcTruthVector.push_back(truth);
 
  635     std::cout << 
"---RAW-MATCHING-OUTPUT--------------------------------------------------------------------------" << std::endl;
 
  637     for (
const art::Ptr<simb::MCTruth> pMCTruth : mcTruthVector)
 
  639         std::cout << 
"MCNeutrino, PDG " << pMCTruth->GetNeutrino().Nu().PdgCode() << 
", InteractionType " << pMCTruth->GetNeutrino().InteractionType() << std::endl;
 
  642     for (
const art::Ptr<recob::PFParticle> pPfo : recoNeutrinoVector)
 
  644         std::cout << 
"RecoNeutrino, PDG " << pPfo->PdgCode() << 
", nDaughters " << pPfo->NumDaughters() << std::endl;
 
  647     for (
const MCPrimaryMatchingMap::value_type &mapValue : mcPrimaryMatchingMap)
 
  664                 << simpleMatchedPfo.
m_nPfoHitsW << 
")" << std::endl;
 
  668     std::cout << 
"------------------------------------------------------------------------------------------------" << std::endl;
 
  676     IntSet usedMCIds, usedPfoIds;
 
  677     while (
GetStrongestPfoMatch(mcPrimaryMatchingMap, usedMCIds, usedPfoIds, matchingDetailsMap)) {}
 
  688     int bestPfoMatchId(-1);
 
  691     for (
const MCPrimaryMatchingMap::value_type &mapValue : mcPrimaryMatchingMap)
 
  698         if (usedMCIds.count(simpleMCPrimary.
m_id))
 
  703             if (usedPfoIds.count(simpleMatchedPfo.
m_id))
 
  706             if (!this->
IsGoodMatch(simpleMCPrimary, simpleMatchedPfo))
 
  711                 bestPfoMatchId = simpleMatchedPfo.
m_id;
 
  719     if (bestPfoMatchId > -1)
 
  721         matchingDetailsMap[bestPfoMatchId] = bestMatchingDetails;
 
  723         usedPfoIds.insert(bestPfoMatchId);
 
  735     for (
const MCPrimaryMatchingMap::value_type &mapValue : mcPrimaryMatchingMap)
 
  744             if (usedPfoIds.count(simpleMatchedPfo.
m_id))
 
  763     std::cout << 
"---PROCESSED-MATCHING-OUTPUT--------------------------------------------------------------------" << std::endl;
 
  767     bool isCorrect(
true), isCalculable(
false);
 
  769     for (
const MCPrimaryMatchingMap::value_type &mapValue : mcPrimaryMatchingMap)
 
  772         const bool hasMatch(this->
HasMatch(simpleMCPrimary, mapValue.second, matchingDetailsMap));
 
  775         if (!hasMatch && !isTargetPrimary)
 
  778         std::cout << std::endl << (!isTargetPrimary ? 
"(Non target) " : 
"")
 
  785         unsigned int nMatches(0);
 
  789             if (matchingDetailsMap.count(simpleMatchedPfo.
m_id) && (simpleMCPrimary.
m_id == matchingDetailsMap.at(simpleMatchedPfo.
m_id).m_matchedPrimaryId))
 
  791                 const bool isGoodMatch(this->
IsGoodMatch(simpleMCPrimary, simpleMatchedPfo));
 
  793                 if (isGoodMatch) ++nMatches;
 
  794                 std::cout << 
"-" << (!isGoodMatch ? 
"(Below threshold) " : 
"") << 
"MatchedPfo " << simpleMatchedPfo.
m_id;
 
  805         if (isTargetPrimary && (1 != nMatches))
 
  809     std::cout << std::endl << 
"Is correct? " << (isCorrect && isCalculable) << std::endl;
 
  810     std::cout << 
"------------------------------------------------------------------------------------------------" << std::endl;
 
  838         if (matchingDetailsMap.count(simpleMatchedPfo.m_id) && (simpleMCPrimary.
m_id == matchingDetailsMap.at(simpleMatchedPfo.m_id).m_matchedPrimaryId))
 
  859     unsigned int nHitsOfSpecifiedType(0);
 
  861     for (
const art::Ptr<recob::Hit> pHit : hitVector)
 
  863         if (view == pHit->View())
 
  864             ++nHitsOfSpecifiedType;
 
  867     return nHitsOfSpecifiedType;
 
  916     return (m_id < rhs.
m_id);
 
  930     m_nMatchedHitsTotal(0),
 
  942     m_matchedPrimaryId(-1),
 
static void BuildPFParticleHitMaps(const PFParticleVector &particleVector, const PFParticlesToSpacePoints &particlesToSpacePoints, const SpacePointsToHits &spacePointsToHits, PFParticlesToHits &particlesToHits, HitsToPFParticles &hitsToParticles, const DaughterMode daughterMode=kUseDaughters)
Build mapping between PFParticles and Hits using PFParticle/SpacePoint/Hit maps. 
 
bool GetStrongestPfoMatch(const MCPrimaryMatchingMap &mcPrimaryMatchingMap, IntSet &usedMCIds, IntSet &usedPfoIds, MatchingDetailsMap &matchingDetailsMap) const 
Get the strongest pfo match (most matched hits) between an available mc primary and an available pfo...
 
int m_pdgCode
The pdg code. 
 
std::vector< art::Ptr< simb::MCTruth > > MCTruthVector
 
void GetMCParticleMatchingMap(const PFParticlesToHits &recoParticlesToHits, const MCParticlesToHits &trueParticlesToHits, const HitsToMCParticles &hitsToTrueParticles, MCParticleMatchingMap &mcParticleMatchingMap) const 
Performing matching between true and reconstructed particles. 
 
std::map< art::Ptr< recob::Hit >, art::Ptr< simb::MCParticle > > HitsToMCParticles
 
bool HasMatch(const SimpleMCPrimary &simpleMCPrimary, const SimpleMatchedPfoList &simpleMatchedPfoList, const MatchingDetailsMap &matchingDetailsMap) const 
Whether a provided mc primary has a match, of any quality (use simple matched pfo list and informatio...
 
bool IsNeutrinoInduced(const art::Ptr< simb::MCParticle > pMCParticle, const MCParticlesToMCTruth &artMCParticlesToMCTruth) const 
Whether a mc particle is neutrino induced. 
 
int m_nMCHitsU
The number of u mc hits. 
 
then if[["$THISISATEST"==1]]
 
int m_nMCHitsTotal
The total number of mc hits. 
 
int m_pdgCode
The pdg code. 
 
void PrintMatchingOutput(const MCPrimaryMatchingMap &mcPrimaryMatchingMap, const MatchingDetailsMap &matchingDetailsMap) const 
Print the results of the matching procedure. 
 
void PerformMatching(const MCPrimaryMatchingMap &mcPrimaryMatchingMap, MatchingDetailsMap &matchingDetailsMap) const 
Apply a well-defined matching procedure to the comprehensive matches in the provided mc primary match...
 
int m_nPfoHitsV
The number of v pfo hits. 
 
int m_nPfoHitsTotal
The total number of pfo hits. 
 
std::map< SimpleMCPrimary, SimpleMatchedPfoList > MCPrimaryMatchingMap
 
PFParticleValidation(fhicl::ParameterSet const &pset)
Constructor. 
 
float m_matchingMinCompleteness
The minimum particle completeness to declare a match. 
 
const simb::MCParticle * m_pAddress
The address of the mc primary. 
 
static bool IsNeutrino(const art::Ptr< recob::PFParticle > particle)
Determine whether a particle has been reconstructed as a neutrino. 
 
enum geo::_plane_proj View_t
Enumerate the possible plane projections. 
 
void GetRecoNeutrinos(const art::Event &evt, PFParticleVector &recoNeutrinoVector) const 
Obtain a vector of reco neutrinos. 
 
SimpleMatchedPfo()
Constructor. 
 
Declaration of signal hit object. 
 
bool m_neutrinoInducedOnly
Whether to consider only mc particles that were neutrino induced. 
 
std::map< art::Ptr< simb::MCParticle >, art::Ptr< simb::MCTruth > > MCParticlesToMCTruth
 
int m_matchingMinPrimaryHits
The minimum number of good mc primary hits used in matching scheme. 
 
void GetSimpleMCPrimaryList(const art::Event &evt, const MCParticlesToHits &mcParticlesToHits, const HitsToMCParticles &hitsToMCParticles, const MCParticleMatchingMap &mcParticleMatchingMap, SimpleMCPrimaryList &simpleMCPrimaryList) const 
Extract details of each mc primary (ordered by number of true hits) 
 
float m_energy
The energy. 
 
int m_nMatchedHitsW
The number of w matched hits. 
 
int m_nMatchedHitsU
The number of u matched hits. 
 
SimpleMCPrimary()
Constructor. 
 
std::map< int, MatchingDetails > MatchingDetailsMap
 
int m_nMCHitsW
The number of w mc hits. 
 
const recob::PFParticle * m_pAddress
The address of the pf primary. 
 
void PrintAllOutput(const MCTruthVector &mcTruthVector, const PFParticleVector &recoNeutrinoVector, const MCPrimaryMatchingMap &mcPrimaryMatchingMap) const 
Print all the raw matching output to screen. 
 
std::string m_particleLabel
The name/label of the particle producer module. 
 
int m_nMatchedPfos
The number of matched pfos. 
 
int m_id
The unique identifier. 
 
bool m_useSmallPrimaries
Whether to consider matches to mc primaries with fewer than m_matchingMinPrimaryHits. 
 
std::vector< SimpleMCPrimary > SimpleMCPrimaryList
 
int m_nPfoHitsW
The number of w pfo hits. 
 
bool m_printMatchingToScreen
Whether to print matching output to screen. 
 
void GetMCTruth(const art::Event &evt, MCTruthVector &mcTruthVector) const 
Obtain a vector of mc truth. 
 
bool IsGoodMatch(const SimpleMCPrimary &simpleMCPrimary, const SimpleMatchedPfo &simpleMatchedPfo) const 
Whether a provided mc primary and pfo are deemed to be a good match. 
 
int m_nMatchedHitsTotal
The total number of matched hits. 
 
std::map< art::Ptr< simb::MCParticle >, HitVector > MCParticlesToHits
 
bool m_printAllToScreen
Whether to print all/raw matching details to screen. 
 
int m_nMatchedHits
The number of times the primary has 0 pfo matches. 
 
std::vector< art::Ptr< recob::PFParticle > > PFParticleVector
 
void analyze(const art::Event &evt)
 
std::map< art::Ptr< simb::MCTruth >, MCParticleVector > MCTruthToMCParticles
 
float m_matchingMinPurity
The minimum particle purity to declare a match. 
 
PFParticleValidation class. 
 
std::string m_backtrackerLabel
The name/label of the back-tracker module. 
 
int m_nMCHitsV
The number of v mc hits. 
 
std::map< art::Ptr< recob::PFParticle >, HitVector > PFParticlesToHits
 
float m_completeness
The completeness of the match. 
 
int m_matchedPrimaryId
The total number of occurences. 
 
MatchingDetails()
Default constructor. 
 
int m_matchingMinSharedHits
The minimum number of shared hits used in matching scheme. 
 
int m_matchingMinPrimaryGoodViews
The minimum number of good views for a mc primary. 
 
void GetRemainingPfoMatches(const MCPrimaryMatchingMap &mcPrimaryMatchingMap, const IntSet &usedPfoIds, MatchingDetailsMap &matchingDetailsMap) const 
Get the best matches for any pfos left-over after the strong matching procedure. 
 
std::vector< SimpleMatchedPfo > SimpleMatchedPfoList
 
static bool SortSimpleMatchedPfos(const SimpleMatchedPfo &lhs, const SimpleMatchedPfo &rhs)
Sort simple matched pfos by number of matched hits. 
 
Definition of data types for geometry description. 
 
std::map< art::Ptr< recob::PFParticle >, HitVector > PFParticleToMatchedHits
 
static void CollectPFParticles(const art::Event &evt, const std::string &label, PFParticleVector &particleVector)
Collect the reconstructed PFParticles from the ART event record. 
 
static void CollectHits(const art::Event &evt, const std::string &label, HitVector &hitVector)
Collect the reconstructed Hits from the ART event record. 
 
int m_nMatchedHitsV
The number of v matched hits. 
 
std::map< art::Ptr< simb::MCParticle >, PFParticleToMatchedHits > MCParticleMatchingMap
 
static void SelectNeutrinoPFParticles(const PFParticleVector &inputParticles, PFParticleVector &outputParticles)
Select reconstructed neutrino particles from a list of all reconstructed particles. 
 
std::vector< art::Ptr< recob::Hit > > HitVector
 
bool IsGoodMCPrimary(const SimpleMCPrimary &simpleMCPrimary) const 
Whether a provided mc primary passes selection, based on number of "good" hits. 
 
Hierarchical representation of particle flow. 
 
int m_matchingMinHitsForGoodView
The minimum number of good mc primary hits in given view to declare view to be good. 
 
int m_nPfoHitsU
The number of u pfo hits. 
 
std::map< art::Ptr< recob::Hit >, art::Ptr< recob::PFParticle > > HitsToPFParticles
 
static bool SortSimpleMCPrimaries(const SimpleMCPrimary &lhs, const SimpleMCPrimary &rhs)
Sort simple mc primaries by number of mc hits. 
 
virtual ~PFParticleValidation()
Destructor. 
 
void reconfigure(fhicl::ParameterSet const &pset)
 
void GetMCPrimaryMatchingMap(const SimpleMCPrimaryList &simpleMCPrimaryList, const MCParticleMatchingMap &mcParticleMatchingMap, const PFParticlesToHits &pfParticlesToHits, MCPrimaryMatchingMap &mcPrimaryMatchingMap) const 
Obtain a sorted list of matched pfos for each mc primary. 
 
Planes which measure W (third view for Bo, MicroBooNE, etc). 
 
bool operator<(const SimpleMCPrimary &rhs) const 
operator < 
 
std::string m_geantModuleLabel
The name/label of the geant module. 
 
static void BuildMCParticleHitMaps(const art::Event &evt, const HitVector &hitVector, const SimChannelVector &simChannelVector, HitsToTrackIDEs &hitsToTrackIDEs)
Collect the links from reconstructed hits to their true energy deposits. 
 
static void CollectMCParticles(const art::Event &evt, const std::string &label, MCParticleVector &particleVector)
Collect a vector of MCParticle objects from the ART event record. 
 
helper function for LArPandoraInterface producer module 
 
unsigned int CountHitsByType(const geo::View_t view, const HitVector &hitVector) const 
Count the number of hits, in a provided vector, of a specified view. 
 
int m_id
The unique identifier. 
 
std::string m_hitfinderLabel
The name/label of the hit producer module. 
 
BEGIN_PROLOG could also be cout
 
int m_parentId
The unique identifier of the parent pfo (-1 if no parent set)