136 const HitsToMCParticles &hitsToTrueParticles, MCParticleMatchingMap &mcParticleMatchingMap)
const;
148 const MCParticleMatchingMap &mcParticleMatchingMap, SimpleMCPrimaryList &simpleMCPrimaryList)
const;
158 void GetMCPrimaryMatchingMap(
const SimpleMCPrimaryList &simpleMCPrimaryList,
const MCParticleMatchingMap &mcParticleMatchingMap,
159 const PFParticlesToHits &pfParticlesToHits, MCPrimaryMatchingMap &mcPrimaryMatchingMap)
const;
202 void PerformMatching(
const MCPrimaryMatchingMap &mcPrimaryMatchingMap, MatchingDetailsMap &matchingDetailsMap)
const;
214 bool GetStrongestPfoMatch(
const MCPrimaryMatchingMap &mcPrimaryMatchingMap, IntSet &usedMCIds, IntSet &usedPfoIds, MatchingDetailsMap &matchingDetailsMap)
const;
223 void GetRemainingPfoMatches(
const MCPrimaryMatchingMap &mcPrimaryMatchingMap,
const IntSet &usedPfoIds, MatchingDetailsMap &matchingDetailsMap)
const;
231 void PrintMatchingOutput(
const MCPrimaryMatchingMap &mcPrimaryMatchingMap,
const MatchingDetailsMap &matchingDetailsMap)
const;
251 bool HasMatch(
const SimpleMCPrimary &simpleMCPrimary,
const SimpleMatchedPfoList &simpleMatchedPfoList,
const MatchingDetailsMap &matchingDetailsMap)
const;
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)
448 const HitVector &hitVector(recoParticleToHits.second);
454 if (hitsToMCParticles.end() == mcParticleIter)
458 mcParticleMatchingMap[pTrueParticle][pRecoParticle].push_back(pHit);
472 for (
const MCParticlesToHits::value_type &mapEntry : mcParticlesToHits)
483 simpleMCPrimary.
m_energy = pMCPrimary->
E();
487 if (mcParticlesToHits.end() != trueHitsIter)
489 const HitVector &hitVector(trueHitsIter->second);
498 if (mcParticleMatchingMap.end() != matchedPfoIter)
501 simpleMCPrimaryList.push_back(simpleMCPrimary);
508 simpleMCPrimary.m_id = mcPrimaryId++;
517 if (artMCParticlesToMCTruth.end() == 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)
549 const HitVector &matchedHitVector(contribution.second);
553 simpleMatchedPfo.
m_id = pMatchedPfo->
Self();
561 if (pMatchedPfo->
Parent() == iter->first->Self())
563 parentPfoIter = iter;
569 simpleMatchedPfo.
m_parentId = parentPfoIter->first->Self();
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)
616 if (mcTruthVector.end() == std::find(mcTruthVector.begin(), mcTruthVector.end(), truth))
617 mcTruthVector.push_back(truth);
635 std::cout <<
"---RAW-MATCHING-OUTPUT--------------------------------------------------------------------------" <<
std::endl;
639 std::cout <<
"MCNeutrino, PDG " << pMCTruth->GetNeutrino().Nu().PdgCode() <<
", InteractionType " << pMCTruth->GetNeutrino().InteractionType() <<
std::endl;
644 std::cout <<
"RecoNeutrino, PDG " << pPfo->PdgCode() <<
", nDaughters " << pPfo->NumDaughters() <<
std::endl;
647 for (
const MCPrimaryMatchingMap::value_type &mapValue : mcPrimaryMatchingMap)
651 std::cout << std::endl <<
"Primary " << simpleMCPrimary.
m_id <<
", PDG " << simpleMCPrimary.
m_pdgCode <<
", nMCHits " << simpleMCPrimary.
m_nMCHitsTotal 656 std::cout <<
"-MatchedPfo " << simpleMatchedPfo.
m_id;
659 std::cout <<
", ParentPfo " << simpleMatchedPfo.
m_parentId;
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);
863 if (view == pHit->View())
864 ++nHitsOfSpecifiedType;
867 return nHitsOfSpecifiedType;
930 m_nMatchedHitsTotal(0),
942 m_matchedPrimaryId(-1),
double E(const int i=0) const
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.
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
size_t Self() const
Returns the index of this particle.
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.
bool m_neutrinoInducedOnly
Whether to consider only mc particles that were neutrino induced.
std::map< art::Ptr< simb::MCParticle >, art::Ptr< simb::MCTruth > > MCParticlesToMCTruth
simb::Origin_t Origin() const
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.
int PdgCode() const
Return the type of particle as a PDG ID.
SimpleMCPrimary()
Constructor.
std::map< int, MatchingDetails > MatchingDetailsMap
EDAnalyzer(fhicl::ParameterSet const &pset)
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.
#define DEFINE_ART_MODULE(klass)
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.
T get(std::string const &key) const
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
Declaration of signal hit object.
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.
cet::coded_exception< error, detail::translate > exception
QTextStream & endl(QTextStream &s)
int m_parentId
The unique identifier of the parent pfo (-1 if no parent set)