13 #include "nusimdata/SimulationBase/MCTruth.h"
15 #include "art/Framework/Principal/Event.h"
16 #include "art/Framework/Principal/Handle.h"
17 #include "canvas/Persistency/Common/FindManyP.h"
23 const std::string &mcParticleLabel,
const std::string &hitLabel,
const std::string &backtrackLabel,
const std::string &pandoraLabel,
28 mcNeutrino = beamNuMCTruth->GetNeutrino();
53 art::Handle< std::vector<simb::MCTruth> > mcTruthHandle;
54 evt.getByLabel(truthLabel, mcTruthHandle);
56 if (!mcTruthHandle.isValid())
57 throw cet::exception(
"LArPandora") <<
" LArPandoraSliceIdHelper::GetBeamNeutrinoMCTruth - invalid MCTruth handle" << std::endl;
60 bool foundNeutrino(
false);
61 float maxNeutrinoEnergy(-std::numeric_limits<float>::max());
62 art::Ptr<simb::MCTruth> beamNuMCTruth;
63 for (
unsigned int i = 0; i < mcTruthHandle->size(); ++i)
65 const art::Ptr<simb::MCTruth> mcTruth(mcTruthHandle, i);
67 if (mcTruth->Origin() != simb::kBeamNeutrino)
70 const float nuEnergy(mcTruth->GetNeutrino().Nu().E());
71 if (nuEnergy < maxNeutrinoEnergy)
75 maxNeutrinoEnergy = nuEnergy;
76 beamNuMCTruth = mcTruth;
81 throw cet::exception(
"LArPandora") <<
" LArPandoraSliceIdHelper::GetBeamNeutrinoMCTruth - found no beam neutrino MCTruth blocks" << std::endl;
89 const std::string &mcParticleLabel,
const art::Ptr<simb::MCTruth> &beamNuMCTruth,
MCParticleVector &mcParticles)
92 art::Handle< std::vector<simb::MCTruth> > mcTruthHandle;
93 evt.getByLabel(truthLabel, mcTruthHandle);
95 if (!mcTruthHandle.isValid())
96 throw cet::exception(
"LArPandora") <<
" LArPandoraSliceIdHelper::CollectNeutrinoMCParticles - invalid MCTruth handle" << std::endl;
99 art::FindManyP<simb::MCParticle> truthToMCParticleAssns(mcTruthHandle, evt, mcParticleLabel);
100 mcParticles = truthToMCParticleAssns.at(beamNuMCTruth.key());
109 art::Handle< std::vector<recob::Hit> > hitHandle;
110 evt.getByLabel(hitLabel, hitHandle);
112 if (!hitHandle.isValid())
113 throw cet::exception(
"LArPandora") <<
" LArPandoraSliceIdHelper::GetHitOrigins - invalid hit handle" << std::endl;
115 art::FindManyP<simb::MCParticle> hitToMCParticleAssns(hitHandle, evt, backtrackLabel);
118 for (
unsigned int i = 0; i < hitHandle->size(); ++i)
120 const art::Ptr<recob::Hit>
hit(hitHandle, i);
123 const auto &particles(hitToMCParticleAssns.at(hit.key()));
125 bool foundNuParticle(
false);
126 for (
const auto &part : particles)
129 if (std::find(mcParticles.begin(), mcParticles.end(), part) == mcParticles.end())
132 foundNuParticle =
true;
136 if (!hitToIsNuInducedMap.emplace(hit, foundNuParticle).second)
137 throw cet::exception(
"LArPandora") <<
" LArPandoraSliceIdHelper::GetHitOrigins - repeated hits in input collection" << std::endl;
145 unsigned int nNuHits(0);
146 for (
const auto &
hit : hits)
148 const auto it(hitToIsNuInducedMap.find(
hit));
150 if (it == hitToIsNuInducedMap.end())
151 throw cet::exception(
"LArPandora") <<
" LArPandoraSliceIdHelper::CountNeutrinoHits - can't find hit in hitToIsNuInducedMap" << std::endl;
153 nNuHits += it->second ? 1 : 0;
164 art::Handle< std::vector<recob::PFParticle> > pfParticleHandle;
165 evt.getByLabel(pandoraLabel, pfParticleHandle);
167 if (!pfParticleHandle.isValid())
168 throw cet::exception(
"LArPandora") <<
" LArPandoraSliceIdHelper::GetPFParticleToHitsMap - invalid PFParticle handle" << std::endl;
171 art::Handle< std::vector<recob::Cluster> > clusterHandle;
172 evt.getByLabel(pandoraLabel, clusterHandle);
174 if (!clusterHandle.isValid())
175 throw cet::exception(
"LArPandora") <<
" LArPandoraSliceIdHelper::GetPFParticleToHitsMap - invalid cluster handle" << std::endl;
178 art::FindManyP<recob::Cluster> pfParticleToClusterAssns(pfParticleHandle, evt, pandoraLabel);
179 art::FindManyP<recob::Hit> clusterToHitAssns(clusterHandle, evt, pandoraLabel);
182 for (
unsigned int iPart = 0; iPart < pfParticleHandle->size(); ++iPart)
184 const art::Ptr<recob::PFParticle> part(pfParticleHandle, iPart);
187 for (
const auto &
cluster : pfParticleToClusterAssns.at(part.key()))
189 for (
const auto &
hit : clusterToHitAssns.at(
cluster.key()))
191 if (std::find(hits.begin(), hits.end(),
hit) != hits.end())
192 throw cet::exception(
"LArPandora") <<
" LArPandoraSliceIdHelper::GetPFParticleToHitsMap - double counted hits!" << std::endl;
198 if (!pfParticleToHitsMap.emplace(part, hits).second)
199 throw cet::exception(
"LArPandora") <<
" LArPandoraSliceIdHelper::GetPFParticleToHitsMap - repeated input PFParticles" << std::endl;
216 for (
const auto &part : pfParticles)
218 const auto it(pfParticleToHitsMap.find(part));
219 if (it == pfParticleToHitsMap.end())
220 throw cet::exception(
"LArPandora") <<
" LArPandoraSliceIdHelper::CollectHits - can't find any hits associated to input PFParticle" << std::endl;
222 for (
const auto &
hit : it->second)
225 if (std::find(hits.begin(), hits.end(),
hit) == hits.end())
236 if (!sliceMetadata.empty())
237 throw cet::exception(
"LArPandora") <<
" LArPandoraSliceIdHelper::GetSliceMetadata - non empty input metadata vector" << std::endl;
242 unsigned int mostCompleteSliceIndex(0);
243 unsigned int maxNuHits(0);
245 for (
unsigned int sliceIndex = 0; sliceIndex < slices.size(); ++sliceIndex)
247 const Slice &slice(slices.at(sliceIndex));
251 const unsigned int nHitsInSlice(hits.size());
254 if (nNuHitsInSlice > maxNuHits)
256 mostCompleteSliceIndex = sliceIndex;
257 maxNuHits = nNuHitsInSlice;
261 metadata.
m_nHits = nHitsInSlice;
262 metadata.
m_purity = ((nHitsInSlice == 0) ? -1.f : static_cast<float>(nNuHitsInSlice) /
static_cast<float>(nHitsInSlice));
263 metadata.
m_completeness = ((nNuHits == 0) ? -1.f : static_cast<float>(nNuHitsInSlice) /
static_cast<float>(nNuHits));
266 sliceMetadata.push_back(metadata);
269 sliceMetadata.at(mostCompleteSliceIndex).m_isMostComplete =
true;
276 m_purity(-
std::numeric_limits<float>::max()),
277 m_completeness(-
std::numeric_limits<float>::max()),
278 m_nHits(
std::numeric_limits<unsigned int>::max()),
279 m_isMostComplete(
false)
std::unordered_map< art::Ptr< recob::Hit >, bool > HitToBoolMap
static unsigned int CountNeutrinoHits(const HitVector &hits, const HitToBoolMap &hitToIsNuInducedMap)
Count the number of hits in an input vector that are neutrino induced.
static void CollectNeutrinoMCParticles(const art::Event &evt, const std::string &truthLabel, const std::string &mcParticleLabel, const art::Ptr< simb::MCTruth > &beamNuMCTruth, MCParticleVector &mcParticles)
Collect all MCParticles that come from the beam neutrino interaction.
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
static void CollectHits(const PFParticleVector &pfParticles, const PFParticlesToHits &pfParticleToHitsMap, HitVector &hits)
Collect the hits in a given vector of PFParticles.
const PFParticleVector & GetCosmicRayHypothesis() const
Get the slice as reconstructed under the cosmic-ray hypothesis.
Declaration of signal hit object.
static void GetPFParticleToHitsMap(const art::Event &evt, const std::string &pandoraLabel, PFParticlesToHits &pfParticleToHitsMap)
Get the mapping from PFParticles to associated hits (via clusters)
static void GetHitOrigins(const art::Event &evt, const std::string &hitLabel, const std::string &backtrackLabel, const MCParticleVector &mcParticles, HitVector &hits, HitToBoolMap &hitToIsNuInducedMap)
For each hit in the event, determine if any of it's charge was deposited by a neutrino induced partic...
std::vector< SliceMetadata > SliceMetadataVector
helper class for slice id tools
static void GetReconstructedHitsInSlice(const Slice &slice, const PFParticlesToHits &pfParticleToHitsMap, HitVector &hits)
Collect the hits in the slice that have been added to a PFParticle (under either reconstruction hypot...
const PFParticleVector & GetTargetHypothesis() const
Get the slice as reconstructed under the target hypothesis.
static void GetSliceMetadata(const SliceVector &slices, const art::Event &evt, const std::string &truthLabel, const std::string &mcParticleLabel, const std::string &hitLabel, const std::string &backtrackLabel, const std::string &pandoraLabel, SliceMetadataVector &sliceMetadata, simb::MCNeutrino &mcNeutrino)
Get MC metadata about each slice.
std::vector< art::Ptr< recob::PFParticle > > PFParticleVector
std::map< art::Ptr< recob::PFParticle >, HitVector > PFParticlesToHits
std::vector< art::Ptr< simb::MCParticle > > MCParticleVector
Declaration of cluster object.
std::vector< TCSlice > slices
std::vector< art::Ptr< recob::Hit > > HitVector
static art::Ptr< simb::MCTruth > GetBeamNeutrinoMCTruth(const art::Event &evt, const std::string &truthLabel)
Get the MCTruth block for the simulated beam neutrino.
std::vector< Slice > SliceVector