7 #include "art/Framework/Core/EDProducer.h"
8 #include "art/Framework/Core/ModuleMacros.h"
9 #include "art/Framework/Principal/Event.h"
10 #include "art/Utilities/make_tool.h"
12 #include "canvas/Utilities/InputTag.h"
14 #include "fhiclcpp/ParameterSet.h"
45 typedef std::map<art::Ptr<recob::PFParticle>, art::Ptr<larpandoraobj::PFParticleMetadata> >
PFParticleToMetadata;
102 float GetMetadataValue(
const art::Ptr<larpandoraobj::PFParticleMetadata> &metadata,
const std::string &key)
const;
111 bool IsTarget(
const art::Ptr<larpandoraobj::PFParticleMetadata> &metadata)
const;
132 #include "Pandora/PdgTable.h"
134 namespace lar_pandora
139 m_inputProducerLabel(pset.get<std::string>(
"InputProducerLabel")),
140 m_trackProducerLabel(pset.get<std::string>(
"TrackProducerLabel")),
141 m_showerProducerLabel(pset.get<std::string>(
"ShowerProducerLabel")),
142 m_hitProducerLabel(pset.get<std::string>(
"HitProducerLabel")),
143 m_shouldProduceT0s(pset.get<
bool>(
"ShouldProduceT0s")),
144 m_pandoraTag(art::InputTag(m_inputProducerLabel)),
145 m_sliceIdTool(art::make_tool<SliceIdBaseTool>(pset.get<fhicl::ParameterSet>(
"SliceIdTool"))),
146 m_useTestBeamMode(pset.get<
bool>(
"ShouldUseTestBeamMode",
false)),
147 m_targetKey(m_useTestBeamMode ?
"IsTestBeam" :
"IsNeutrino"),
148 m_scoreKey(m_useTestBeamMode ?
"TestBeamScore" :
"NuScore")
150 produces< std::vector<recob::PFParticle> >();
151 produces< std::vector<recob::SpacePoint> >();
152 produces< std::vector<recob::Cluster> >();
153 produces< std::vector<recob::Vertex> >();
154 produces< std::vector<recob::Slice> >();
155 produces< std::vector<recob::Track> >();
156 produces< std::vector<recob::Shower> >();
157 produces< std::vector<recob::PCAxis> >();
158 produces< std::vector<larpandoraobj::PFParticleMetadata> >();
160 produces< art::Assns<recob::PFParticle, recob::SpacePoint> >();
161 produces< art::Assns<recob::PFParticle, recob::Cluster> >();
162 produces< art::Assns<recob::PFParticle, recob::Vertex> >();
163 produces< art::Assns<recob::PFParticle, recob::Slice> >();
164 produces< art::Assns<recob::PFParticle, recob::Track> >();
165 produces< art::Assns<recob::PFParticle, recob::Shower> >();
166 produces< art::Assns<recob::PFParticle, recob::PCAxis> >();
167 produces< art::Assns<recob::PFParticle, larpandoraobj::PFParticleMetadata> >();
168 produces< art::Assns<recob::Track, recob::Hit, recob::TrackHitMeta> >();
169 produces< art::Assns<recob::Shower, recob::Hit> >();
170 produces< art::Assns<recob::Shower, recob::PCAxis> >();
171 produces< art::Assns<recob::SpacePoint, recob::Hit> >();
172 produces< art::Assns<recob::Cluster, recob::Hit> >();
173 produces< art::Assns<recob::Slice, recob::Hit> >();
175 if (m_shouldProduceT0s)
177 produces< std::vector<anab::T0> >();
178 produces< art::Assns<recob::PFParticle, anab::T0> >();
197 this->
CollectSlices(particles, particlesToMetadata, particleMap, slices);
214 art::Handle<std::vector<recob::PFParticle> > pfParticleHandle;
217 art::FindManyP<larpandoraobj::PFParticleMetadata> pfParticleMetadataAssoc(pfParticleHandle, evt,
m_pandoraTag);
219 for (
unsigned int i = 0; i < pfParticleHandle->size(); ++i)
221 const art::Ptr<recob::PFParticle> part(pfParticleHandle, i);
222 const auto &metadata(pfParticleMetadataAssoc.at(part.key()));
224 particles.push_back(part);
226 if (metadata.size() != 1)
227 throw cet::exception(
"LArPandora") <<
" LArPandoraExternalEventBuilding::CollectPFParticles -- Found a PFParticle without exactly 1 metadata associated." << std::endl;
229 if (!particlesToMetadata.insert(PFParticleToMetadata::value_type(part, metadata.front())).second)
230 throw cet::exception(
"LArPandoraExternalEventBuilding") <<
"Repeated PFParticles" << std::endl;
238 for (
const auto &entry : particlesToMetadata)
240 if (!particleMap.insert(PFParticleMap::value_type(entry.first->Self(), entry.first)).second)
241 throw cet::exception(
"LArPandoraExternalEventBuilding") <<
"Repeated PFParticles" << std::endl;
249 for (
const auto &part : allParticles)
253 if (parentIt == particlesToMetadata.end())
254 throw cet::exception(
"LArPandoraExternalEventBuilding") <<
"Found PFParticle without metadata" << std::endl;
259 if (static_cast<bool>(std::round(this->
GetMetadataValue(parentIt->second,
"IsClearCosmic"))))
260 clearCosmics.push_back(part);
262 catch (
const cet::exception &)
272 std::map<unsigned int, float> targetScores;
273 std::map<unsigned int, PFParticleVector> crHypotheses;
274 std::map<unsigned int, PFParticleVector> targetHypotheses;
275 std::vector<unsigned int> usedSliceIds;
278 for (
const auto &part : allParticles)
282 if (parentIt == particlesToMetadata.end())
283 throw cet::exception(
"LArPandoraExternalEventBuilding") <<
"Found PFParticle without metadata" << std::endl;
288 if (static_cast<bool>(std::round(this->
GetMetadataValue(parentIt->second,
"IsClearCosmic"))))
291 catch (
const cet::exception &)
295 const unsigned int sliceId(static_cast<unsigned int>(std::round(this->
GetMetadataValue(parentIt->second,
"SliceIndex"))));
299 if (std::find(usedSliceIds.begin(), usedSliceIds.end(), sliceId) == usedSliceIds.end())
301 usedSliceIds.push_back(sliceId);
304 targetScores[sliceId] = targetScore;
307 if (this->
IsTarget(parentIt->second))
309 targetHypotheses[sliceId].push_back(part);
313 crHypotheses[sliceId].push_back(part);
318 std::sort(usedSliceIds.begin(), usedSliceIds.end());
325 for (
const unsigned int sliceId : usedSliceIds)
328 const auto targetScoresIter(targetScores.find(sliceId));
329 if (targetScoresIter == targetScores.end())
330 throw cet::exception(
"LArPandoraExternalEventBuilding") <<
"Scrambled slice information - can't find target score with id = " << sliceId << std::endl;
335 const auto targetHypothesisIter(targetHypotheses.find(sliceId));
336 targetPFParticleVector = ((targetHypothesisIter == targetHypotheses.end()) ? emptyPFParticleVector : targetHypothesisIter->second);
339 const auto crHypothesisIter(crHypotheses.find(sliceId));
340 crPFParticleVector = ((crHypothesisIter == crHypotheses.end()) ? emptyPFParticleVector : crHypothesisIter->second);
341 slices.emplace_back(targetScoresIter->second, targetPFParticleVector, crPFParticleVector);
349 const auto &propertiesMap(metadata->GetPropertiesMap());
350 const auto &it(propertiesMap.find(key));
352 if (it == propertiesMap.end())
353 throw cet::exception(
"LArPandoraExternalEventBuilding") <<
"No key \"" << key <<
"\" found in metadata properties map" << std::endl;
363 collectedParticles.insert(collectedParticles.end(), clearCosmics.begin(), clearCosmics.end());
365 for (
const auto &slice : slices)
367 const PFParticleVector &particles(slice.IsTaggedAsTarget() ? slice.GetTargetHypothesis() : slice.GetCosmicRayHypothesis());
368 collectedParticles.insert(collectedParticles.end(), particles.begin(), particles.end());
373 for (
const auto &part : allParticles)
375 if (std::find(collectedParticles.begin(), collectedParticles.end(), part) != collectedParticles.end())
376 consolidatedParticles.push_back(part);
388 catch (
const cet::exception &)
void CollectSlices(const PFParticleVector &allParticles, const PFParticleToMetadata &particlesToMetadata, const PFParticleMap &particleMap, SliceVector &slices) const
Collect slices.
void CollectPFParticles(const art::Event &evt, PFParticleToMetadata &particlesToMetadata, PFParticleVector &particles) const
Collect PFParticles from the ART event and their mapping to metadata objects.
std::unique_ptr< SliceIdBaseTool > m_sliceIdTool
The slice id tool.
std::map< art::Ptr< recob::PFParticle >, art::Ptr< larpandoraobj::PFParticleMetadata > > PFParticleToMetadata
LArPandoraExternalEventBuilding & operator=(LArPandoraExternalEventBuilding const &)=delete
static art::Ptr< recob::PFParticle > GetParentPFParticle(const PFParticleMap &particleMap, const art::Ptr< recob::PFParticle > daughterParticle)
Return the top-level parent particle by navigating up the chain of parent/daughter associations...
std::map< int, art::Ptr< recob::PFParticle > > PFParticleMap
void CollectClearCosmicRays(const PFParticleVector &allParticles, const PFParticleToMetadata &particlesToMetadata, const PFParticleMap &particleMap, PFParticleVector &clearCosmics) const
Collect PFParticles that have been identified as clear cosmic ray muons by pandora.
std::string m_trackProducerLabel
Label for the track producer using the Pandora instance that produced the collections we want to cons...
std::string m_showerProducerLabel
Label for the shower producer using the Pandora instance that produced the collections we want to con...
std::string m_hitProducerLabel
Label for the hit producer that was used as input to the Pandora instance specified.
A description of all outputs from an instance of pandora with functionality to filter and merge multi...
std::vector< art::Ptr< recob::PFParticle > > PFParticleVector
std::string m_targetKey
The metadata key for a PFParticle to determine if it is the target.
header for the lar pandora slice class
std::string m_scoreKey
The metadata key for the score of the target slice from Pandora.
std::vector< TCSlice > slices
void produce(art::Event &evt) override
float GetMetadataValue(const art::Ptr< larpandoraobj::PFParticleMetadata > &metadata, const std::string &key) const
Query a metadata object for a given key and return the corresponding value.
std::vector< Slice > SliceVector
bool m_useTestBeamMode
If we should expect a test-beam (instead of a neutrino) slice.
bool m_shouldProduceT0s
If we should produce T0s (relevant when stitching over multiple drift volumes)
art::InputTag m_pandoraTag
The input tag for the pandora producer.
Class to handle the required producer labels.
std::string m_inputProducerLabel
Label for the Pandora instance that produced the collections we want to consolidated.
void BuildPFParticleMap(const PFParticleToMetadata &particlesToMetadata, PFParticleMap &particleMap) const
Build mapping from ID to PFParticle for fast navigation through the hierarchy.
void CollectConsolidatedParticles(const PFParticleVector &allParticles, const PFParticleVector &clearCosmics, const SliceVector &slices, PFParticleVector &consolidatedParticles) const
Get the consolidated collection of particles based on the slice ids.
bool IsTarget(const art::Ptr< larpandoraobj::PFParticleMetadata > &metadata) const
Query a metadata object to see if it is a target particle.
helper function for LArPandoraInterface producer module
LArPandoraExternalEventBuilding(fhicl::ParameterSet const &pset)
void WriteToEvent() const
Write (put) the collections in this LArPandoraEvent to the art::Event.