9#include "art/Framework/Principal/Event.h"
10#include "cetlib_except/exception.h"
11#include "messagefacility/MessageLogger/MessageLogger.h"
13#include "lardata/Utilities/AssociationUtil.h"
14#include "lardata/Utilities/GeometryUtilities.h"
15#include "larreco/ClusterFinder/ClusterCreator.h"
16#include "larreco/RecoAlg/ClusterParamsImportWrapper.h"
17#include "larreco/RecoAlg/ClusterRecoUtil/StandardClusterParamsAlg.h"
19#include "larcore/Geometry/Geometry.h"
20#include "lardata/DetectorInfoServices/DetectorClocksService.h"
21#include "lardata/DetectorInfoServices/DetectorPropertiesService.h"
22#include "lardataobj/RecoBase/Hit.h"
46 const std::string instanceLabel(
48 const std::string testBeamInteractionVertexInstanceLabel(
57 new std::vector<larpandoraobj::PFParticleMetadata>);
69 new art::Assns<recob::PFParticle, larpandoraobj::PFParticleMetadata>);
71 new art::Assns<recob::PFParticle, recob::SpacePoint>);
73 new art::Assns<recob::PFParticle, recob::Cluster>);
75 new art::Assns<recob::PFParticle, recob::Vertex>);
78 new art::Assns<recob::SpacePoint, recob::Hit>);
84 new art::Assns<recob::PFParticle, recob::Vertex> :
103 pfoToTestBeamInteractionVerticesMap,
118 clusterList, threeDHitList, idToHitMap, pandoraHitToArtHitMap);
125 outputTestBeamInteractionVertices);
130 pandoraHitToArtHitMap,
132 outputSpacePointsToHits);
138 pandoraHitToArtHitMap,
141 outputClustersToHits,
142 pfoToArtClustersMap);
151 outputParticlesToVertices,
152 outputParticlesToSpacePoints,
153 outputParticlesToClusters);
156 evt, instanceLabel, pfoVector, outputParticleMetadata, outputParticlesToMetadata);
166 outputParticlesToSlices,
176 pfoToTestBeamInteractionVerticesMap,
177 outputParticlesToTestBeamInteractionVertices);
180 evt.put(std::move(outputParticles), instanceLabel);
181 evt.put(std::move(outputSpacePoints), instanceLabel);
182 evt.put(std::move(outputClusters), instanceLabel);
183 evt.put(std::move(outputVertices), instanceLabel);
184 evt.put(std::move(outputParticleMetadata), instanceLabel);
186 evt.put(std::move(outputParticlesToMetadata), instanceLabel);
187 evt.put(std::move(outputParticlesToSpacePoints), instanceLabel);
188 evt.put(std::move(outputParticlesToClusters), instanceLabel);
189 evt.put(std::move(outputParticlesToVertices), instanceLabel);
190 evt.put(std::move(outputParticlesToSlices), instanceLabel);
191 evt.put(std::move(outputSpacePointsToHits), instanceLabel);
192 evt.put(std::move(outputClustersToHits), instanceLabel);
195 evt.put(std::move(outputTestBeamInteractionVertices), testBeamInteractionVertexInstanceLabel);
196 evt.put(std::move(outputParticlesToTestBeamInteractionVertices),
197 testBeamInteractionVertexInstanceLabel);
201 evt.put(std::move(outputT0s), instanceLabel);
202 evt.put(std::move(outputParticlesToT0s), instanceLabel);
206 evt.put(std::move(outputSlices), instanceLabel);
207 evt.put(std::move(outputSlicesToHits), instanceLabel);
214 const std::string& name,
217 if (!pPrimaryPandora)
218 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::GetPandoraInstance--- input "
219 "primary pandora instance address is invalid ";
221 if (pPandoraInstance)
222 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::GetPandoraInstance--- the input "
223 "pandora instance address is non-null ";
227 if (pPandora->GetName() != name)
continue;
229 if (pPandoraInstance)
230 throw cet::exception(
"LArPandora")
231 <<
" LArPandoraOutput::GetPandoraInstance--- found multiple pandora instances with name: "
234 pPandoraInstance = pPandora;
237 return static_cast<bool>(pPandoraInstance);
245 if (!slicePfos.empty())
246 throw cet::exception(
"LArPandora")
247 <<
" LArPandoraOutput::GetPandoraSlices--- Input slicePfo vector is not empty ";
260 slicePfos.insert(slicePfos.end(), pSlicePfoList->begin(), pSlicePfoList->end());
277 throw cet::exception(
"LArPandora")
278 <<
" LArPandoraOutput::CollectAllPfoOutcomes--- Can't find slice nu worker instance. ";
282 throw cet::exception(
"LArPandora")
283 <<
" LArPandoraOutput::CollectAllPfoOutcomes--- Can't find slice CR worker instance. ";
286 for (
unsigned int sliceIndex = 0; sliceIndex < slicePfos.size(); ++sliceIndex) {
288 if (pandora::STATUS_CODE_SUCCESS ==
290 *pSliceNuWorker,
"NeutrinoParticles3D" + std::to_string(sliceIndex), pNuPfoList))
291 collectedPfos.insert(collectedPfos.end(), pNuPfoList->begin(), pNuPfoList->end());
294 if (pandora::STATUS_CODE_SUCCESS ==
296 *pSliceCRWorker,
"MuonParticles3D" + std::to_string(sliceIndex), pCRPfoList))
297 collectedPfos.insert(collectedPfos.end(), pCRPfoList->begin(), pCRPfoList->end());
325 const auto it(properties.find(
"IsClearCosmic"));
327 if (it == properties.end())
return false;
329 return static_cast<bool>(std::round(it->second));
339 return (properties.find(
"SliceIndex") != properties.end());
349 const auto it(properties.find(
"SliceIndex"));
351 if (it == properties.end())
352 throw cet::exception(
"LArPandora")
353 <<
" LArPandoraOutput::GetSliceIndex--- Input PFO was not from a slice ";
355 return static_cast<unsigned int>(std::round(it->second));
378 if (!pfoVector.empty())
379 throw cet::exception(
"LArPandora")
380 <<
" LArPandoraOutput::CollectPfos--- trying to collect pfos into a non-empty list ";
385 pfoVector.insert(pfoVector.end(), pfoList.begin(), pfoList.end());
398 for (
unsigned int pfoId = 0; pfoId < pfoVector.size(); ++pfoId) {
407 const auto it(std::find(vertexVector.begin(), vertexVector.end(), pVertex));
408 const bool isInList(it != vertexVector.end());
409 const size_t vertexId(isInList ? std::distance(vertexVector.begin(), it) :
410 vertexVector.size());
412 if (!isInList) vertexVector.push_back(pVertex);
414 if (!pfoToVerticesMap.insert(IdToIdVectorMap::value_type(pfoId, {vertexId})).second)
415 throw cet::exception(
"LArPandora")
416 <<
" LArPandoraOutput::CollectVertices --- repeated pfos in input list ";
433 for (
unsigned int pfoId = 0; pfoId < pfoVector.size(); ++pfoId) {
442 IdVector clusterIds(clusters.size());
443 std::iota(clusterIds.begin(), clusterIds.end(), clusterList.size());
445 clusterList.insert(clusterList.end(), clusters.begin(), clusters.end());
447 if (!pfoToClustersMap.insert(IdToIdVectorMap::value_type(pfoId, clusterIds)).second)
448 throw cet::exception(
"LArPandora")
449 <<
" LArPandoraOutput::CollectClusters --- repeated pfos in input list ";
462 for (
unsigned int pfoId = 0; pfoId < pfoVector.size(); ++pfoId) {
465 if (!pfoToThreeDHitsMap.insert(IdToIdVectorMap::value_type(pfoId, {})).second)
466 throw cet::exception(
"LArPandora")
467 <<
" LArPandoraOutput::Collect3DHits --- repeated pfos in input list ";
476 throw cet::exception(
"LArPandora")
477 <<
" LArPandoraOutput::Collect3DHits --- found a 2D hit in a 3D cluster";
479 pfoToThreeDHitsMap.at(pfoId).push_back(caloHitList.size());
480 caloHitList.push_back(pCaloHit3D);
496 caloHits.insert(caloHits.end(), threeDHits.begin(), threeDHits.end());
510 throw cet::exception(
"LArPandora")
511 <<
" LArPandoraOutput::GetPandoraToArtHitMap --- found a 3D input cluster ";
517 if (!pandoraHitToArtHitMap
518 .insert(CaloHitToArtHitMap::value_type(
521 throw cet::exception(
"LArPandora")
522 <<
" LArPandoraOutput::GetPandoraToArtHitMap --- found repeated input hits ";
528 throw cet::exception(
"LArPandora")
529 <<
" LArPandoraOutput::GetPandoraToArtHitMap --- found a non-3D hit in the input list ";
532 if (!pandoraHitToArtHitMap
533 .insert(CaloHitToArtHitMap::value_type(
536 idToHitMap,
static_cast<const pandora::CaloHit*
>(pCaloHit->GetParentAddress()))))
538 throw cet::exception(
"LArPandora")
539 <<
" LArPandoraOutput::GetPandoraToArtHitMap --- found repeated input hits ";
552 for (
unsigned int depth = 0, maxDepth = 2; depth < maxDepth; ++depth) {
555 for (
unsigned int i = 0; i < depth; ++i)
560 const intptr_t hitID_temp((intptr_t)(pHitAddress));
561 const int hitID((
int)(hitID_temp));
563 IdToHitMap::const_iterator artIter = idToHitMap.find(hitID);
566 if (idToHitMap.end() == artIter)
continue;
568 return artIter->second;
571 throw cet::exception(
"LArPandora")
572 <<
" LArPandoraOutput::GetHit --- found a Pandora hit without a parent ART hit ";
580 for (
size_t vertexId = 0; vertexId < vertexVector.size(); ++vertexId)
587 const std::string& instanceLabel,
594 threeDHitVector.insert(threeDHitVector.end(), threeDHitList.begin(), threeDHitList.end());
596 for (
unsigned int hitId = 0; hitId < threeDHitVector.size(); hitId++) {
599 CaloHitToArtHitMap::const_iterator it(pandoraHitToArtHitMap.find(pCaloHit));
600 if (it == pandoraHitToArtHitMap.end())
601 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::BuildSpacePoints --- found a "
602 "pandora hit without a corresponding art hit ";
605 event, instanceLabel, hitId, {it->second}, outputSpacePointsToHits);
613 const std::string& instanceLabel,
621 cluster::StandardClusterParamsAlg clusterParamAlgo;
623 art::ServiceHandle<geo::Geometry const> geom{};
624 auto const clock_data =
625 art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(event);
626 auto const det_prop =
627 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(event, clock_data);
628 util::GeometryUtilities
const gser{*geom, clock_data, det_prop};
631 size_t nextClusterId(0);
634 std::vector<HitVector> hitVectors;
635 const std::vector<recob::Cluster> clusters(
639 pandoraHitToArtHitMap,
640 pandoraClusterToArtClustersMap,
645 if (hitVectors.size() != clusters.size())
646 throw cet::exception(
"LArPandora")
647 <<
" LArPandoraOutput::BuildClusters --- invalid hit vectors for clusters produced ";
649 for (
unsigned int i = 0; i < clusters.size(); ++i) {
651 event, instanceLabel, nextClusterId - 1, hitVectors.at(i), outputClustersToHits);
652 outputClusters->push_back(clusters.at(i));
657 for (IdToIdVectorMap::const_iterator it = pfoToClustersMap.begin();
658 it != pfoToClustersMap.end();
660 if (!pfoToArtClustersMap.insert(IdToIdVectorMap::value_type(it->first, {})).second)
661 throw cet::exception(
"LArPandora")
662 <<
" LArPandoraOutput::BuildClusters --- repeated pfo ids ";
664 for (
const size_t pandoraClusterId : it->second) {
665 IdToIdVectorMap::const_iterator it2(pandoraClusterToArtClustersMap.find(pandoraClusterId));
667 if (it2 == pandoraClusterToArtClustersMap.end())
668 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::BuildClusters --- found a "
669 "pandora cluster with no associated recob cluster ";
671 for (
const size_t recobClusterId : it2->second)
672 pfoToArtClustersMap.at(it->first).push_back(recobClusterId);
680 const art::Event& event,
681 const std::string& instanceLabel,
691 for (
unsigned int pfoId = 0; pfoId < pfoVector.size(); ++pfoId) {
697 if (pfoToVerticesMap.find(pfoId) != pfoToVerticesMap.end())
699 event, instanceLabel, pfoId, pfoToVerticesMap, outputParticlesToVertices);
701 if (pfoToThreeDHitsMap.find(pfoId) != pfoToThreeDHitsMap.end())
703 event, instanceLabel, pfoId, pfoToThreeDHitsMap, outputParticlesToSpacePoints);
705 if (pfoToArtClustersMap.find(pfoId) != pfoToArtClustersMap.end())
707 event, instanceLabel, pfoId, pfoToArtClustersMap, outputParticlesToClusters);
714 const art::Event& event,
715 const std::string& instanceLabel,
720 for (
unsigned int pfoId = 0; pfoId < pfoVector.size(); ++pfoId) {
721 if (pfoToVerticesMap.find(pfoId) != pfoToVerticesMap.end())
723 event, instanceLabel, pfoId, pfoToVerticesMap, outputParticlesToVertices);
730 const art::Event& event,
731 const std::string& instanceLabel,
736 for (
unsigned int pfoId = 0; pfoId < pfoVector.size(); ++pfoId) {
740 event, instanceLabel, pfoId, outputParticleMetadata->size(), outputParticlesToMetadata);
741 larpandoraobj::PFParticleMetadata pPFParticleMetadata(
743 outputParticleMetadata->push_back(pPFParticleMetadata);
751 const art::Event& event,
752 const std::string& instanceLabel,
767 outputParticlesToSlices,
779 pSlicePfo, event, instanceLabel, idToHitMap, outputSlices, outputSlicesToHits);
782 std::unordered_map<const pandora::ParticleFlowObject*, unsigned int> parentPfoToSliceIndexMap;
783 for (
unsigned int pfoId = 0; pfoId < pfoVector.size(); ++pfoId) {
791 if (!parentPfoToSliceIndexMap
794 pPfo, event, instanceLabel, idToHitMap, outputSlices, outputSlicesToHits))
796 throw cet::exception(
"LArPandora")
797 <<
" LArPandoraOutput::BuildSlices --- found repeated primary particles ";
801 for (
unsigned int pfoId = 0; pfoId < pfoVector.size(); ++pfoId) {
810 outputParticlesToSlices);
817 if (parentPfoToSliceIndexMap.find(pParent) == parentPfoToSliceIndexMap.end())
818 throw cet::exception(
"LArPandora")
819 <<
" LArPandoraOutput::BuildSlices --- found pfo without a parent in the input list ";
823 event, instanceLabel, pfoId, parentPfoToSliceIndexMap.at(pParent), outputParticlesToSlices);
832 const float bogusFloat(std::numeric_limits<float>::max());
833 const recob::tracking::Point_t bogusPoint(bogusFloat, bogusFloat, bogusFloat);
834 const recob::tracking::Vector_t bogusVector(bogusFloat, bogusFloat, bogusFloat);
836 const unsigned int sliceIndex(outputSlices->size());
837 outputSlices->emplace_back(
838 sliceIndex, bogusPoint, bogusVector, bogusPoint, bogusPoint, bogusFloat, bogusFloat);
847 const art::Event& event,
848 const std::string& instanceLabel,
864 mf::LogDebug(
"LArPandora") <<
" - Found " << hits.size() << std::endl;
865 mf::LogDebug(
"LArPandora") <<
" - Making associations " << outputSlicesToHits->size()
869 for (
unsigned int pfoId = 0; pfoId < pfoVector.size(); ++pfoId)
871 event, instanceLabel, pfoId, sliceIndex, outputParticlesToSlices);
877 const art::Event& event,
878 const std::string& instanceLabel,
914 const std::string& instanceLabel,
920 for (
unsigned int pfoId = 0; pfoId < pfoVector.size(); ++pfoId) {
927 event, instanceLabel, pfoId, nextT0Id - 1, outputParticlesToT0s);
928 outputT0s->push_back(t0);
940 if (parentList.size() > 1)
941 throw cet::exception(
"LArPandora")
942 <<
" LArPandoraOutput::BuildPFParticle --- this pfo has multiple parent particles ";
944 const size_t parentId(parentList.empty() ?
945 recob::PFParticle::kPFParticlePrimary :
949 std::vector<size_t> daughterIds;
953 std::sort(daughterIds.begin(), daughterIds.end());
955 return recob::PFParticle(pPfo->
GetParticleId(), pfoId, parentId, daughterIds);
961 const size_t vertexId)
965 return recob::Vertex(pos, vertexId);
973 if (!sortedHits.empty())
974 throw cet::exception(
"LArPandora")
975 <<
" LArPandoraOutput::GetHitsInCluster --- vector to hold hits is not empty ";
979 hitList.insert(hitList.end(),
983 sortedHits.insert(sortedHits.end(), hitList.begin(), hitList.end());
991 util::GeometryUtilities
const& gser,
996 std::vector<HitVector>& hitVectors,
998 cluster::ClusterParamsAlgBase& algo)
1000 std::vector<recob::Cluster> clusters;
1004 if (!pandoraClusterToArtClustersMap.insert(IdToIdVectorMap::value_type(clusterId, {})).second)
1005 throw cet::exception(
"LArPandora")
1006 <<
" LArPandoraOutput::BuildClusters --- repeated clusters in input list ";
1015 CaloHitToArtHitMap::const_iterator it(pandoraHitToArtHitMap.find(pCaloHit2D));
1016 if (it == pandoraHitToArtHitMap.end())
1017 throw cet::exception(
"LArPandora")
1018 <<
" LArPandoraOutput::BuildClusters --- couldn't find art hit for input pandora hit ";
1020 const art::Ptr<recob::Hit> hit(it->second);
1022 const geo::WireID wireID(hit->WireID());
1023 const unsigned int volID(100000 * wireID.Cryostat + wireID.TPC);
1024 hitArray[volID].push_back(hit);
1026 if (pCaloHit2D->IsIsolated()) isolatedHits.insert(hit);
1029 if (hitArray.empty())
1030 throw cet::exception(
"LArPandora")
1031 <<
" LArPandoraOutput::BuildClusters --- found a cluster with no hits ";
1033 for (
const HitArray::value_type& hitArrayEntry : hitArray) {
1034 const HitVector& clusterHits(hitArrayEntry.second);
1038 hitVectors.push_back(clusterHits);
1039 pandoraClusterToArtClustersMap.at(clusterId).push_back(nextId);
1053 cluster::ClusterParamsAlgBase& algo)
1055 if (hitVector.empty())
1056 throw cet::exception(
"LArPandora")
1057 <<
" LArPandoraOutput::BuildCluster --- No input hits were provided ";
1060 geo::View_t view(geo::kUnknown);
1061 geo::PlaneID planeID;
1063 double startWire(+std::numeric_limits<float>::max()), sigmaStartWire(0.0);
1064 double startTime(+std::numeric_limits<float>::max()), sigmaStartTime(0.0);
1065 double endWire(-std::numeric_limits<float>::max()), sigmaEndWire(0.0);
1066 double endTime(-std::numeric_limits<float>::max()), sigmaEndTime(0.0);
1068 std::vector<recob::Hit const*> hits_for_params;
1069 hits_for_params.reserve(hitVector.size());
1071 for (
const art::Ptr<recob::Hit>& hit : hitVector) {
1072 const double thisWire(hit->WireID().Wire);
1073 const double thisWireSigma(0.5);
1074 const double thisTime(hit->PeakTime());
1075 const double thisTimeSigma(
double(2. * hit->RMS()));
1076 const geo::View_t thisView(hit->View());
1077 const geo::PlaneID thisPlaneID(hit->WireID().planeID());
1079 if (geo::kUnknown == view) {
1081 planeID = thisPlaneID;
1084 if (!(thisView == view && thisPlaneID == planeID)) {
1085 throw cet::exception(
"LArPandora")
1086 <<
" LArPandoraOutput::BuildCluster --- Input hits have inconsistent plane IDs ";
1089 hits_for_params.push_back(&*hit);
1091 if (isolatedHits.count(hit))
continue;
1093 if (thisWire < startWire || (thisWire == startWire && thisTime < startTime)) {
1094 startWire = thisWire;
1095 sigmaStartWire = thisWireSigma;
1096 startTime = thisTime;
1097 sigmaStartTime = thisTimeSigma;
1100 if (thisWire > endWire || (thisWire == endWire && thisTime > endTime)) {
1102 sigmaEndWire = thisWireSigma;
1104 sigmaEndTime = thisTimeSigma;
1109 algo.SetHits(gser, hits_for_params);
1112 return cluster::ClusterCreator(gser,
1125 recob::Cluster::Sentry
1133 const size_t spacePointId)
1136 throw cet::exception(
"LArPandora")
1137 <<
" LArPandoraOutput::BuildSpacePoint --- trying to build a space point from a 2D hit";
1140 double xyz[3] = {point.
GetX(), point.
GetY(), point.
GetZ()};
1143 double dxdydz[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
1146 return recob::SpacePoint(xyz, dxdydz, chi2, spacePointId);
1161 auto const clock_data = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(e);
1162 auto const det_prop =
1163 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(e, clock_data);
1164 const double cm_per_tick(det_prop.GetXTicksCoefficient());
1165 const double ns_per_tick(sampling_rate(clock_data));
1168 const double T0(x0 * ns_per_tick / cm_per_tick);
1170 if (std::fabs(T0) <= std::numeric_limits<double>::epsilon())
return false;
1182 : m_pPrimaryPandora(nullptr)
1183 , m_shouldRunStitching(false)
1184 , m_shouldProduceAllOutcomes(false)
1185 , m_shouldProduceTestBeamInteractionVertices(false)
1186 , m_isNeutrinoRecoOnlyNoSlicing(false)
1193 if (!m_pPrimaryPandora)
1194 throw cet::exception(
"LArPandora")
1195 <<
" LArPandoraOutput::Settings::Validate --- primary Pandora instance does not exist ";
1197 if (!m_shouldProduceAllOutcomes)
return;
1199 if (m_allOutcomesInstanceLabel.empty())
1200 throw cet::exception(
"LArPandora")
1201 <<
" LArPandoraOutput::Settings::Validate --- all outcomes instance label not set ";
Header file for the calo hit class.
Header file for the cluster class.
Header file for the cluster helper class.
Helper functions for processing outputs from pandora.
Header file for the pfo helper class.
Header file for the MultiPandoraApi class.
Header file for the particle flow object class.
#define PANDORA_THROW_RESULT_IF(StatusCode1, Operator, Command)
Header file for the vertex class.
static const PandoraInstanceList & GetDaughterPandoraInstanceList(const pandora::Pandora *const pPrimaryPandora)
Get the list of daughter pandora instances associated with a given primary pandora instance.
static pandora::StatusCode GetPfoList(const pandora::Pandora &pandora, const std::string &pfoListName, const pandora::PfoList *&pPfoList)
Get a named pfo list.
static pandora::StatusCode GetCurrentPfoList(const pandora::Pandora &pandora, const pandora::PfoList *&pPfoList)
Get the current pfo list.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
static bool SortHitsByPosition(const pandora::CaloHit *const pLhs, const pandora::CaloHit *const pRhs)
Sort calo hits by their position (use Z, followed by X, followed by Y)
static bool SortByNHits(const pandora::Cluster *const pLhs, const pandora::Cluster *const pRhs)
Sort clusters by number of hits, then layer span, then inner layer, then position,...
static void GetAllConnectedPfos(const pandora::PfoList &inputPfoList, pandora::PfoList &outputPfoList)
Get a flat list of all pfos, recursively including all daughters and parents associated with those pf...
static const pandora::ParticleFlowObject * GetParentPfo(const pandora::ParticleFlowObject *const pPfo)
Get the primary parent pfo.
static void GetTwoDClusterList(const pandora::ParticleFlowObject *const pPfo, pandora::ClusterList &clusterList)
Get the list of 2D clusters from an input pfo.
static void GetIsolatedCaloHits(const pandora::PfoList &pfoList, const pandora::HitType &hitType, pandora::CaloHitList &caloHitList)
Get a list of isolated calo hits of a particular hit type from a list of pfos.
static bool SortByNHits(const pandora::ParticleFlowObject *const pLhs, const pandora::ParticleFlowObject *const pRhs)
Sort pfos by number of constituent hits.
static const pandora::Vertex * GetTestBeamInteractionVertex(const pandora::ParticleFlowObject *const pPfo)
Get the pfo test beam interaction vertex.
static void GetCaloHits(const pandora::PfoList &pfoList, const pandora::HitType &hitType, pandora::CaloHitList &caloHitList)
Get a list of calo hits of a particular hit type from a list of pfos.
static const pandora::Vertex * GetVertex(const pandora::ParticleFlowObject *const pPfo)
Get the pfo vertex.
static void CollectHits(const art::Event &evt, const std::string &label, HitVector &hitVector)
Collect the reconstructed Hits from the ART event record.
static larpandoraobj::PFParticleMetadata GetPFParticleMetadata(const pandora::ParticleFlowObject *const pPfo)
Get metadata associated to a PFO.
void Validate() const
Check the parameters and throw an exception if they are not valid.
std::string m_testBeamInteractionVerticesInstanceLabel
The label for the test beam interaction vertices.
std::string m_allOutcomesInstanceLabel
The label for the instance producing all outcomes.
std::string m_hitfinderModuleLabel
The hit finder module label.
bool m_shouldProduceTestBeamInteractionVertices
Whether to write the test beam interaction vertices in a separate collection.
bool m_isNeutrinoRecoOnlyNoSlicing
If we are running the neutrino reconstruction only with no slicing.
Settings()
Default constructor.
bool m_shouldProduceAllOutcomes
If all outcomes should be produced in separate collections (choose false if you only require the cons...
const pandora::Pandora * m_pPrimaryPandora
bool m_shouldProduceSlices
Whether to produce output slices e.g. may not want to do this if only (re)processing single slices.
bool m_shouldRunStitching
static pandora::VertexVector CollectVertices(const pandora::PfoVector &pfoVector, IdToIdVectorMap &pfoToVerticesMap, std::function< const pandora::Vertex *const(const pandora::ParticleFlowObject *const)> fCriteria)
Collect all vertices contained in the input pfo list Order is guaranteed provided pfoVector is ordere...
std::unique_ptr< art::Assns< recob::PFParticle, recob::Cluster > > PFParticleToClusterCollection
static void AssociateAdditionalVertices(const art::Event &event, const std::string &instanceLabel, const pandora::PfoVector &pfoVector, const IdToIdVectorMap &pfoToVerticesMap, PFParticleToVertexCollection &outputParticlesToVertices)
Convert Create the associations between pre-existing PFParticle and additional vertices.
static void AddAssociation(const art::Event &event, const std::string &instanceLabel, const size_t idA, const size_t idB, std::unique_ptr< art::Assns< A, B > > &association)
Add an association between objects with two given ids.
static bool IsClearCosmic(const pandora::ParticleFlowObject *const pPfo)
Check if the input pfo is an unambiguous cosmic ray.
std::unique_ptr< art::Assns< recob::PFParticle, recob::Vertex > > PFParticleToVertexCollection
static recob::Cluster BuildCluster(util::GeometryUtilities const &gser, const size_t id, const HitVector &hitVector, const HitList &isolatedHits, cluster::ClusterParamsAlgBase &algo)
Build an ART cluster from an input vector of ART hits.
static void ProduceArtOutput(const Settings &settings, const IdToHitMap &idToHitMap, art::Event &evt)
Convert the Pandora PFOs into ART clusters and write into ART event.
std::unique_ptr< art::Assns< recob::PFParticle, recob::SpacePoint > > PFParticleToSpacePointCollection
static void GetHitsInCluster(const pandora::Cluster *const pCluster, pandora::CaloHitVector &sortedHits)
Collect a sorted list of all 2D hits in a cluster.
std::unique_ptr< std::vector< recob::Cluster > > ClusterCollection
static art::Ptr< recob::Hit > GetHit(const IdToHitMap &idToHitMap, const pandora::CaloHit *const pCaloHit)
Look up ART hit from an input Pandora hit.
static void BuildT0s(const art::Event &event, const std::string &instanceLabel, const pandora::PfoVector &pfoVector, T0Collection &outputT0s, PFParticleToT0Collection &outputParticlesToT0s)
Calculate the T0 of each pfos and add them to the output vector Create the associations between PFPar...
std::unique_ptr< art::Assns< recob::Cluster, recob::Hit > > ClusterToHitCollection
std::unique_ptr< std::vector< larpandoraobj::PFParticleMetadata > > PFParticleMetadataCollection
std::unique_ptr< std::vector< recob::Slice > > SliceCollection
static void CopyAllHitsToSingleSlice(const Settings &settings, const art::Event &event, const std::string &instanceLabel, const pandora::PfoVector &pfoVector, const IdToHitMap &idToHitMap, SliceCollection &outputSlices, PFParticleToSliceCollection &outputParticlesToSlices, SliceToHitCollection &outputSlicesToHits)
Ouput a single slice containing all of the input hits.
static pandora::PfoVector CollectPfos(const pandora::Pandora *const pPrimaryPandora)
Collect the current pfos (including all downstream pfos) from the master pandora instance.
static pandora::ClusterList CollectClusters(const pandora::PfoVector &pfoVector, IdToIdVectorMap &pfoToClustersMap)
Collect a sorted list of all 2D clusters contained in the input pfo list Order is guaranteed provided...
static recob::PFParticle BuildPFParticle(const pandora::ParticleFlowObject *const pPfo, const size_t pfoId, const pandora::PfoVector &pfoVector)
Convert from a pfo to and ART PFParticle.
static void BuildSlices(const Settings &settings, const pandora::Pandora *const pPrimaryPandora, const art::Event &event, const std::string &instanceLabel, const pandora::PfoVector &pfoVector, const IdToHitMap &idToHitMap, SliceCollection &outputSlices, PFParticleToSliceCollection &outputParticlesToSlices, SliceToHitCollection &outputSlicesToHits)
Build slices - collections of hits which each describe a single particle hierarchy.
std::unique_ptr< std::vector< recob::PFParticle > > PFParticleCollection
static unsigned int BuildDummySlice(SliceCollection &outputSlices)
Build a new slice object with dummy information.
static bool GetPandoraInstance(const pandora::Pandora *const pPrimaryPandora, const std::string &name, const pandora::Pandora *&pPandoraInstance)
Get the address of a pandora instance with a given name.
static recob::SpacePoint BuildSpacePoint(const pandora::CaloHit *const pCaloHit, const size_t spacePointId)
Convert from a pandora 3D hit to an ART spacepoint.
std::map< size_t, IdVector > IdToIdVectorMap
static bool IsFromSlice(const pandora::ParticleFlowObject *const pPfo)
Check if the input pfo is from a slice.
static void Collect3DHits(const pandora::ParticleFlowObject *const pPfo, pandora::CaloHitVector &caloHits)
Collect a sorted vector of all 3D hits in the input pfo.
std::unique_ptr< std::vector< recob::SpacePoint > > SpacePointCollection
static void GetPandoraToArtHitMap(const pandora::ClusterList &clusterList, const pandora::CaloHitList &threeDHitList, const IdToHitMap &idToHitMap, CaloHitToArtHitMap &pandoraHitToArtHitMap)
Collect all 2D and 3D hits that were used / produced in the reconstruction and map them to their corr...
static void BuildPFParticles(const art::Event &event, const std::string &instanceLabel, const pandora::PfoVector &pfoVector, const IdToIdVectorMap &pfoToVerticesMap, const IdToIdVectorMap &pfoToThreeDHitsMap, const IdToIdVectorMap &pfoToArtClustersMap, PFParticleCollection &outputParticles, PFParticleToVertexCollection &outputParticlesToVertices, PFParticleToSpacePointCollection &outputParticlesToSpacePoints, PFParticleToClusterCollection &outputParticlesToClusters)
Convert between pfos and PFParticles and add them to the output vector Create the associations betwee...
static void BuildVertices(const pandora::VertexVector &vertexVector, VertexCollection &outputVertices)
Convert pandora vertices to ART vertices and add them to the output vector.
static void BuildSpacePoints(const art::Event &event, const std::string &instanceLabel, const pandora::CaloHitList &threeDHitList, const CaloHitToArtHitMap &pandoraHitToArtHitMap, SpacePointCollection &outputSpacePoints, SpacePointToHitCollection &outputSpacePointsToHits)
Convert pandora 3D hits to ART spacepoints and add them to the output vector Create the associations ...
std::unique_ptr< std::vector< recob::Vertex > > VertexCollection
static void GetPandoraSlices(const pandora::Pandora *const pPrimaryPandora, pandora::PfoVector &slicePfos)
Get the slice pfos - one pfo per slice.
std::unique_ptr< art::Assns< recob::PFParticle, recob::Slice > > PFParticleToSliceCollection
static unsigned int BuildSlice(const pandora::ParticleFlowObject *const pParentPfo, const art::Event &event, const std::string &instanceLabel, const IdToHitMap &idToHitMap, SliceCollection &outputSlices, SliceToHitCollection &outputSlicesToHits)
Build a new slice object from a PFO, this can be a top-level parent in a hierarchy or a "slice PFO" f...
static size_t GetId(const T *const pT, const std::list< const T * > &tList)
Find the index of an input object in an input list. Throw an exception if it doesn't exist.
std::vector< size_t > IdVector
std::unique_ptr< art::Assns< recob::Slice, recob::Hit > > SliceToHitCollection
static unsigned int GetSliceIndex(const pandora::ParticleFlowObject *const pPfo)
Get the index of the slice from which this pfo was produced.
static pandora::PfoVector CollectAllPfoOutcomes(const pandora::Pandora *const pPrimaryPandora)
Collect the pfos (including all downstream pfos) from the master and daughter pandora instances.
static recob::Vertex BuildVertex(const pandora::Vertex *const pVertex, const size_t vertexId)
Convert from a pandora vertex to an ART vertex.
static void BuildParticleMetadata(const art::Event &event, const std::string &instanceLabel, const pandora::PfoVector &pfoVector, PFParticleMetadataCollection &outputParticleMetadata, PFParticleToMetadataCollection &outputParticlesToMetadata)
Build metadata objects from a list of input pfos.
std::unique_ptr< std::vector< anab::T0 > > T0Collection
std::unique_ptr< art::Assns< recob::PFParticle, larpandoraobj::PFParticleMetadata > > PFParticleToMetadataCollection
static void BuildClusters(const art::Event &event, const std::string &instanceLabel, const pandora::ClusterList &clusterList, const CaloHitToArtHitMap &pandoraHitToArtHitMap, const IdToIdVectorMap &pfoToClustersMap, ClusterCollection &outputClusters, ClusterToHitCollection &outputClustersToHits, IdToIdVectorMap &pfoToArtClustersMap)
Convert pandora 2D clusters to ART clusters and add them to the output vector Create the associations...
std::unique_ptr< art::Assns< recob::SpacePoint, recob::Hit > > SpacePointToHitCollection
std::unique_ptr< art::Assns< recob::PFParticle, anab::T0 > > PFParticleToT0Collection
static bool BuildT0(const art::Event &event, const pandora::ParticleFlowObject *const pPfo, const pandora::PfoVector &pfoVector, size_t &nextId, anab::T0 &t0)
If required, build a T0 for the input pfo.
std::map< const pandora::CaloHit *, art::Ptr< recob::Hit > > CaloHitToArtHitMap
HitType GetHitType() const
Get the calorimeter hit type.
const CartesianVector & GetPositionVector() const
Get the position vector of center of calorimeter cell, units mm.
const void * GetParentAddress() const
Get the address of the parent calo hit in the user framework.
float GetX() const
Get the cartesian x coordinate.
float GetZ() const
Get the cartesian z coordinate.
float GetY() const
Get the cartesian y coordinate.
const OrderedCaloHitList & GetOrderedCaloHitList() const
Get the ordered calo hit list.
const CaloHitList & GetIsolatedCaloHitList() const
Get the isolated calo hit list.
void FillCaloHitList(CaloHitList &caloHitList) const
Fill a provided calo hit list with all the calo hits in the ordered calo hit list.
ParticleFlowObject class.
const PropertiesMap & GetPropertiesMap() const
Get the map from registered property name to floating point property value.
const PfoList & GetDaughterPfoList() const
Get the daughter pfo list.
const PfoList & GetParentPfoList() const
Get the parent pfo list.
const VertexList & GetVertexList() const
Get the vertex list.
int GetParticleId() const
Get the particle flow object id (PDG code)
StatusCodeException class.
const CartesianVector & GetPosition() const
Get the vertex position.
std::vector< art::Ptr< recob::Hit > > HitVector
std::map< int, art::Ptr< recob::Hit > > IdToHitMap
std::set< art::Ptr< recob::Hit > > HitList
std::map< int, HitVector > HitArray
HitType
Calorimeter hit type enum.
std::vector< const CaloHit * > CaloHitVector
MANAGED_CONTAINER< const Cluster * > ClusterList
std::vector< const ParticleFlowObject * > PfoVector
MANAGED_CONTAINER< const CaloHit * > CaloHitList
MANAGED_CONTAINER< const ParticleFlowObject * > PfoList
std::vector< const Vertex * > VertexVector