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)