9 #include "cetlib_except/exception.h" 29 #include "Api/PandoraApi.h" 31 #include "Objects/CaloHit.h" 32 #include "Objects/Cluster.h" 33 #include "Objects/ParticleFlowObject.h" 34 #include "Objects/Vertex.h" 100 LArPandoraOutput::BuildPFParticles(evt, settings.
m_pProducer, instanceLabel, pfoVector, pfoToVerticesMap, pfoToThreeDHitsMap, pfoToArtClustersMap, outputParticles, outputParticlesToVertices, outputParticlesToSpacePoints, outputParticlesToClusters);
109 evt.
put(std::move(outputParticles), instanceLabel);
110 evt.
put(std::move(outputSpacePoints), instanceLabel);
111 evt.
put(std::move(outputClusters), instanceLabel);
112 evt.
put(std::move(outputVertices), instanceLabel);
113 evt.
put(std::move(outputParticleMetadata), instanceLabel);
114 evt.
put(std::move(outputSlices), instanceLabel);
116 evt.
put(std::move(outputParticlesToMetadata), instanceLabel);
117 evt.
put(std::move(outputParticlesToSpacePoints), instanceLabel);
118 evt.
put(std::move(outputParticlesToClusters), instanceLabel);
119 evt.
put(std::move(outputParticlesToVertices), instanceLabel);
120 evt.
put(std::move(outputParticlesToSlices), instanceLabel);
121 evt.
put(std::move(outputSpacePointsToHits), instanceLabel);
122 evt.
put(std::move(outputClustersToHits), instanceLabel);
123 evt.
put(std::move(outputSlicesToHits), instanceLabel);
127 evt.
put(std::move(outputT0s), instanceLabel);
128 evt.
put(std::move(outputParticlesToT0s), instanceLabel);
135 const pandora::Pandora *&pPandoraInstance)
137 if (!pPrimaryPandora)
138 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::GetPandoraInstance--- input primary pandora instance address is invalid ";
140 if (pPandoraInstance)
141 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::GetPandoraInstance--- the input pandora instance address is non-null ";
145 if (pPandora->GetName() != name)
148 if (pPandoraInstance)
149 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::GetPandoraInstance--- found multiple pandora instances with name: " << name;
151 pPandoraInstance = pPandora;
154 return static_cast<bool>(pPandoraInstance);
161 if (!slicePfos.empty())
162 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::GetPandoraSlices--- Input slicePfo vector is not empty ";
165 const pandora::Pandora *pSlicingWorker(
nullptr);
170 const pandora::PfoList *pSlicePfoList(
nullptr);
171 PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::GetCurrentPfoList(*pSlicingWorker, pSlicePfoList));
173 slicePfos.insert(slicePfos.end(), pSlicePfoList->begin(), pSlicePfoList->end());
180 pandora::PfoList collectedPfos;
183 pandora::PfoVector slicePfos;
187 const pandora::Pandora *pSliceNuWorker(
nullptr);
189 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::CollectAllPfoOutcomes--- Can't find slice nu worker instance. ";
191 const pandora::Pandora *pSliceCRWorker(
nullptr);
193 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::CollectAllPfoOutcomes--- Can't find slice CR worker instance. ";
196 for (
unsigned int sliceIndex = 0; sliceIndex < slicePfos.size(); ++sliceIndex)
198 const pandora::PfoList *pNuPfoList(
nullptr);
199 if (pandora::STATUS_CODE_SUCCESS == PandoraApi::GetPfoList(*pSliceNuWorker,
"NeutrinoParticles3D" +
std::to_string(sliceIndex), pNuPfoList))
200 collectedPfos.insert(collectedPfos.end(), pNuPfoList->begin(), pNuPfoList->end());
202 const pandora::PfoList *pCRPfoList(
nullptr);
203 if (pandora::STATUS_CODE_SUCCESS == PandoraApi::GetPfoList(*pSliceCRWorker,
"MuonParticles3D" +
std::to_string(sliceIndex), pCRPfoList))
204 collectedPfos.insert(collectedPfos.end(), pCRPfoList->begin(), pCRPfoList->end());
208 const pandora::PfoList *pParentPfoList(
nullptr);
209 PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::GetCurrentPfoList(*pPrimaryPandora, pParentPfoList));
212 for (
const pandora::ParticleFlowObject *
const pPfo : *pParentPfoList)
215 collectedPfos.push_back(pPfo);
219 pandora::PfoVector pfoVector;
231 const auto &properties(pParent->GetPropertiesMap());
232 const auto it(properties.find(
"IsClearCosmic"));
234 if (it == properties.end())
237 return static_cast<bool>(std::round(it->second));
246 const auto &properties(pParent->GetPropertiesMap());
247 return (properties.find(
"SliceIndex") != properties.end());
256 const auto &properties(pParent->GetPropertiesMap());
257 const auto it(properties.find(
"SliceIndex"));
259 if (it == properties.end())
260 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::GetSliceIndex--- Input PFO was not from a slice ";
262 return static_cast<unsigned int>(std::round(it->second));
269 const pandora::PfoList *pParentPfoList(
nullptr);
270 PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::GetCurrentPfoList(*pPrimaryPandora, pParentPfoList));
272 pandora::PfoVector pfoVector;
282 if (!pfoVector.empty())
283 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::CollectPfos--- trying to collect pfos into a non-empty list ";
285 pandora::PfoList pfoList;
288 pfoVector.insert(pfoVector.end(), pfoList.begin(), pfoList.end());
298 for (
unsigned int pfoId = 0; pfoId < pfoVector.size(); ++pfoId)
300 const pandora::ParticleFlowObject *
const pPfo(pfoVector.at(pfoId));
302 if (pPfo->GetVertexList().empty())
308 const auto it(std::find(vertexVector.begin(), vertexVector.end(), pVertex));
309 const bool isInList(it != vertexVector.end());
310 const size_t vertexId(isInList ? std::distance(vertexVector.begin(), it) : vertexVector.size());
313 vertexVector.push_back(pVertex);
315 if (!pfoToVerticesMap.insert(IdToIdVectorMap::value_type(pfoId, {vertexId})).second)
316 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::CollectVertices --- repeated pfos in input list ";
326 pandora::ClusterList clusterList;
328 for (
unsigned int pfoId = 0; pfoId < pfoVector.size(); ++pfoId)
330 const pandora::ParticleFlowObject *
const pPfo(pfoVector.at(pfoId));
333 pandora::ClusterList clusters;
338 IdVector clusterIds(clusters.size());
339 std::iota(clusterIds.begin(), clusterIds.end(), clusterList.size());
341 clusterList.insert(clusterList.end(), clusters.begin(), clusters.end());
343 if (!pfoToClustersMap.insert(IdToIdVectorMap::value_type(pfoId, clusterIds)).second)
344 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::CollectClusters --- repeated pfos in input list ";
354 pandora::CaloHitList caloHitList;
356 for (
unsigned int pfoId = 0; pfoId < pfoVector.size(); ++pfoId)
358 const pandora::ParticleFlowObject *
const pPfo(pfoVector.at(pfoId));
360 if (!pfoToThreeDHitsMap.insert(IdToIdVectorMap::value_type(pfoId, {})).second)
361 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::Collect3DHits --- repeated pfos in input list ";
363 pandora::CaloHitVector sorted3DHits;
366 for (
const pandora::CaloHit *
const pCaloHit3D : sorted3DHits)
368 if (pandora::TPC_3D != pCaloHit3D->GetHitType())
369 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::Collect3DHits --- found a 2D hit in a 3D cluster";
371 pfoToThreeDHitsMap.at(pfoId).push_back(caloHitList.size());
372 caloHitList.push_back(pCaloHit3D);
384 pandora::CaloHitList threeDHits;
387 caloHits.insert(caloHits.end(), threeDHits.begin(), threeDHits.end());
397 for (
const pandora::Cluster *
const pCluster : clusterList)
400 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::GetPandoraToArtHitMap --- found a 3D input cluster ";
402 pandora::CaloHitVector sortedHits;
405 for (
const pandora::CaloHit *
const pCaloHit : sortedHits)
407 if (!pandoraHitToArtHitMap.insert(CaloHitToArtHitMap::value_type(pCaloHit,
LArPandoraOutput::GetHit(idToHitMap, pCaloHit))).second)
408 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::GetPandoraToArtHitMap --- found repeated input hits ";
412 for (
const pandora::CaloHit *
const pCaloHit : threeDHitList)
414 if (pCaloHit->GetHitType() != pandora::TPC_3D)
415 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::GetPandoraToArtHitMap --- found a non-3D hit in the input list ";
418 if (!pandoraHitToArtHitMap.insert(CaloHitToArtHitMap::value_type(pCaloHit,
LArPandoraOutput::GetHit(idToHitMap, static_cast<const pandora::CaloHit*>(pCaloHit->GetParentAddress())))).second)
419 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::GetPandoraToArtHitMap --- found repeated input hits ";
431 for (
unsigned int depth = 0, maxDepth = 2; depth < maxDepth; ++depth)
434 const pandora::CaloHit *pParentCaloHit = pCaloHit;
435 for (
unsigned int i = 0; i < depth; ++i)
436 pParentCaloHit = static_cast<const pandora::CaloHit *>(pCaloHit->GetParentAddress());
439 const void *
const pHitAddress(pParentCaloHit->GetParentAddress());
440 const intptr_t hitID_temp((intptr_t)(pHitAddress));
441 const int hitID((
int)(hitID_temp));
446 if (idToHitMap.end() == artIter)
449 return artIter->second;
452 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::GetHit --- found a Pandora hit without a parent ART hit ";
459 for (
size_t vertexId = 0; vertexId < vertexVector.size(); ++vertexId)
469 pandora::CaloHitVector threeDHitVector;
470 threeDHitVector.insert(threeDHitVector.end(), threeDHitList.begin(), threeDHitList.end());
472 for (
unsigned int hitId = 0; hitId < threeDHitVector.size(); hitId++)
474 const pandora::CaloHit *
const pCaloHit(threeDHitVector.at(hitId));
477 if (it == pandoraHitToArtHitMap.end())
478 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::BuildSpacePoints --- found a pandora hit without a corresponding art hit ";
494 size_t nextClusterId(0);
496 for (
const pandora::Cluster *
const pCluster : clusterList)
498 std::vector<HitVector> hitVectors;
499 const std::vector<recob::Cluster> clusters(
LArPandoraOutput::BuildClusters(pCluster, clusterList, pandoraHitToArtHitMap, pandoraClusterToArtClustersMap, hitVectors, nextClusterId, clusterParamAlgo));
501 if (hitVectors.size() != clusters.size())
502 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::BuildClusters --- invalid hit vectors for clusters produced ";
504 for (
unsigned int i = 0; i < clusters.size(); ++i)
507 outputClusters->push_back(clusters.at(i));
514 if (!pfoToArtClustersMap.insert(IdToIdVectorMap::value_type(it->first, {})).second)
515 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::BuildClusters --- repeated pfo ids ";
517 for (
const size_t pandoraClusterId : it->second)
521 if (it2 == pandoraClusterToArtClustersMap.end())
522 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::BuildClusters --- found a pandora cluster with no associated recob cluster ";
524 for (
const size_t recobClusterId : it2->second)
525 pfoToArtClustersMap.at(it->first).push_back(recobClusterId);
537 for (
unsigned int pfoId = 0; pfoId < pfoVector.size(); ++pfoId)
539 const pandora::ParticleFlowObject *
const pPfo(pfoVector.at(pfoId));
544 if (pfoToVerticesMap.find(pfoId) != pfoToVerticesMap.end())
547 if (pfoToThreeDHitsMap.find(pfoId) != pfoToThreeDHitsMap.end())
550 if (pfoToArtClustersMap.find(pfoId) != pfoToArtClustersMap.end())
561 for (
unsigned int pfoId = 0; pfoId < pfoVector.size(); ++pfoId)
563 const pandora::ParticleFlowObject *
const pPfo(pfoVector.at(pfoId));
567 outputParticleMetadata->push_back(pPFParticleMetadata);
574 const art::EDProducer *
const pProducer,
const std::string &instanceLabel,
const pandora::PfoVector &pfoVector,
586 pandora::PfoVector slicePfos;
590 for (
const pandora::ParticleFlowObject *
const pSlicePfo : slicePfos)
594 std::unordered_map<const pandora::ParticleFlowObject *, unsigned int> parentPfoToSliceIndexMap;
595 for (
unsigned int pfoId = 0; pfoId < pfoVector.size(); ++pfoId)
597 const pandora::ParticleFlowObject *
const pPfo(pfoVector.at(pfoId));
606 if (!parentPfoToSliceIndexMap.emplace(pPfo,
LArPandoraOutput::BuildSlice(pPfo, event, pProducer, instanceLabel, idToHitMap, outputSlices, outputSlicesToHits)).second)
607 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::BuildSlices --- found repeated primary particles ";
611 for (
unsigned int pfoId = 0; pfoId < pfoVector.size(); ++pfoId)
613 const pandora::ParticleFlowObject *
const pPfo(pfoVector.at(pfoId));
624 if (parentPfoToSliceIndexMap.find(pParent) == parentPfoToSliceIndexMap.end())
625 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::BuildSlices --- found pfo without a parent in the input list ";
641 const unsigned int sliceIndex(outputSlices->size());
642 outputSlices->emplace_back(sliceIndex, bogusPoint, bogusVector, bogusPoint, bogusPoint, bogusFloat, bogusFloat);
650 const std::string &instanceLabel,
const pandora::PfoVector &pfoVector,
const IdToHitMap &idToHitMap,
SliceCollection &outputSlices,
661 mf::LogDebug(
"LArPandora") <<
" - Found " << hits.size() << std::endl;
662 mf::LogDebug(
"LArPandora") <<
" - Making associations " << outputSlicesToHits->size() << std::endl;
665 for (
unsigned int pfoId = 0; pfoId < pfoVector.size(); ++pfoId)
678 pandora::PfoList pfosInSlice;
683 pandora::CaloHitList
hits;
684 for (
const pandora::ParticleFlowObject *
const pPfo : pfosInSlice)
686 for (
const pandora::HitType &hitType : {pandora::TPC_VIEW_U, pandora::TPC_VIEW_V, pandora::TPC_VIEW_W})
694 for (
const pandora::CaloHit *
const pCaloHit : hits)
707 for (
unsigned int pfoId = 0; pfoId < pfoVector.size(); ++pfoId)
709 const pandora::ParticleFlowObject *
const pPfo(pfoVector.at(pfoId));
715 outputT0s->push_back(t0);
724 const pandora::PfoList &parentList(pPfo->GetParentPfoList());
725 if (parentList.size() > 1)
726 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::BuildPFParticle --- this pfo has multiple parent particles ";
731 std::vector<size_t> daughterIds;
732 for (
const pandora::ParticleFlowObject *
const pDaughterPfo : pPfo->GetDaughterPfoList())
735 std::sort(daughterIds.begin(), daughterIds.end());
744 double pos[3] = {pVertex->GetPosition().GetX(), pVertex->GetPosition().GetY(), pVertex->GetPosition().GetZ()};
752 if (!sortedHits.empty())
753 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::GetHitsInCluster --- vector to hold hits is not empty ";
755 pandora::CaloHitList hitList;
756 pCluster->GetOrderedCaloHitList().FillCaloHitList(hitList);
757 hitList.insert(hitList.end(), pCluster->GetIsolatedCaloHitList().begin(), pCluster->GetIsolatedCaloHitList().end());
759 sortedHits.insert(sortedHits.end(), hitList.begin(), hitList.end());
769 std::vector<recob::Cluster> clusters;
773 if (!pandoraClusterToArtClustersMap.insert(IdToIdVectorMap::value_type(clusterId, {})).second)
774 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::BuildClusters --- repeated clusters in input list ";
776 pandora::CaloHitVector sortedHits;
782 for (
const pandora::CaloHit *
const pCaloHit2D : sortedHits)
785 if (it == pandoraHitToArtHitMap.end())
786 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::BuildClusters --- couldn't find art hit for input pandora hit ";
791 const unsigned int volID(100000 * wireID.Cryostat + wireID.TPC);
792 hitArray[volID].push_back(hit);
794 if (pCaloHit2D->IsIsolated())
795 isolatedHits.insert(hit);
798 if (hitArray.empty())
799 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::BuildClusters --- found a cluster with no hits ";
801 for (
const HitArray::value_type &hitArrayEntry : hitArray)
803 const HitVector &clusterHits(hitArrayEntry.second);
806 hitVectors.push_back(clusterHits);
807 pandoraClusterToArtClustersMap.at(clusterId).push_back(nextId);
819 if (hitVector.empty())
820 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::BuildCluster --- No input hits were provided ";
831 std::vector<recob::Hit const*> hits_for_params;
832 hits_for_params.reserve(hitVector.size());
836 const double thisWire(
hit->WireID().Wire);
837 const double thisWireSigma(0.5);
838 const double thisTime(
hit->PeakTime());
839 const double thisTimeSigma(
double(2.*
hit->RMS()));
846 planeID = thisPlaneID;
849 if (!(thisView == view && thisPlaneID == planeID))
851 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::BuildCluster --- Input hits have inconsistent plane IDs ";
854 hits_for_params.push_back(&*
hit);
856 if (isolatedHits.count(
hit))
859 if (thisWire < startWire || (thisWire == startWire && thisTime < startTime))
861 startWire = thisWire;
862 sigmaStartWire = thisWireSigma;
863 startTime = thisTime;
864 sigmaStartTime = thisTimeSigma;
867 if (thisWire > endWire || (thisWire == endWire && thisTime > endTime))
870 sigmaEndWire = thisWireSigma;
872 sigmaEndTime = thisTimeSigma;
902 if (pandora::TPC_3D != pCaloHit->GetHitType())
903 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::BuildSpacePoint --- trying to build a space point from a 2D hit";
905 const pandora::CartesianVector point(pCaloHit->GetPositionVector());
906 double xyz[3] = { point.GetX(), point.GetY(), point.GetZ() };
909 double dxdydz[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
920 pandora::CaloHitVector sorted3DHits;
923 double sumT(0.), sumN(0.);
925 for (
const pandora::CaloHit *
const pCaloHit3D : sorted3DHits)
927 if (pandora::TPC_3D != pCaloHit3D->GetHitType())
928 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::BuildT0 --- found a 2D hit in a 3D cluster";
930 const pandora::CaloHit *
const pCaloHit2D =
static_cast<const pandora::CaloHit*
>(pCaloHit3D->GetParentAddress());
933 if (it == pandoraHitToArtHitMap.end())
934 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::BuildClusters --- couldn't find art hit for input pandora hit ";
939 spacePointHits.push_back(hit);
947 const double T0((sumN > 0. && std::fabs(sumT) > sumN) ? (sumT / sumN) : 0.);
949 if (std::fabs(T0) <= std::numeric_limits<double>::epsilon())
return false;
962 auto const* theDetector = lar::providerFrom<detinfo::DetectorPropertiesService>();
968 const double input_xpos_cm(theDetector->ConvertTicksToX(hit->
PeakTime(), hit_WireID.Plane, hit_WireID.TPC, hit_WireID.Cryostat));
969 const double output_xpos_dm(pCaloHit->GetPositionVector().GetX());
970 const double x0_cm(output_xpos_dm - input_xpos_cm);
973 const double dir((theTpc.DriftDirection() ==
geo::kNegX) ? 1.0 : -1.0);
974 const double cm_per_tick(theDetector->GetXTicksCoefficient());
975 const double ns_per_tick(theDetector->SamplingRate());
978 return (- dir * x0_cm * ns_per_tick / cm_per_tick);
985 m_pPrimaryPandora(nullptr),
986 m_pProducer(nullptr),
987 m_shouldRunStitching(false),
988 m_shouldProduceAllOutcomes(false),
989 m_isNeutrinoRecoOnlyNoSlicing(false)
998 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::Settings::Validate --- primary Pandora instance does not exist ";
1001 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::Settings::Validate --- pointer to ART Producer module does not exist ";
1006 throw cet::exception(
"LArPandora") <<
" LArPandoraOutput::Settings::Validate --- all outcomes instance label not set ";
static void BuildPFParticles(const art::Event &event, const art::EDProducer *const pProducer, 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...
code to link reconstructed objects back to the MC truth information
static pandora::VertexVector CollectVertices(const pandora::PfoVector &pfoVector, IdToIdVectorMap &pfoToVerticesMap)
Collect all vertices contained in the input pfo list Order is guaranteed provided pfoVector is ordere...
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, then pulse-height.
static recob::SpacePoint BuildSpacePoint(const pandora::CaloHit *const pCaloHit, const size_t spacePointId)
Convert from a pandora 3D hit to an ART spacepoint.
std::unique_ptr< art::Assns< recob::PFParticle, anab::T0 > > PFParticleToT0Collection
art::EDProducer * m_pProducer
void Validate() const
Check the parameters and throw an exception if they are not valid.
static void CopyAllHitsToSingleSlice(const Settings &settings, const art::Event &event, const art::EDProducer *const pProducer, 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 void GetPandoraSlices(const pandora::Pandora *const pPrimaryPandora, pandora::PfoVector &slicePfos)
Get the slice pfos - one pfo per slice.
static bool SortByNHits(const pandora::ParticleFlowObject *const pLhs, const pandora::ParticleFlowObject *const pRhs)
Sort pfos by number of constituent hits.
std::unique_ptr< std::vector< recob::Cluster > > ClusterCollection
Header file for the pfo helper class.
static recob::Cluster BuildCluster(const size_t id, const HitVector &hitVector, const HitList &isolatedHits, cluster::ClusterParamsAlgBase &algo)
Build an ART cluster from an input vector of ART hits.
Class managing the creation of a new recob::Cluster object.
const pandora::Pandora * m_pPrimaryPandora
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 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 constexpr size_t kPFParticlePrimary
Define index to signify primary particle.
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
static void GetTwoDClusterList(const pandora::ParticleFlowObject *const pPfo, pandora::ClusterList &clusterList)
Get the list of 2D clusters from an input pfo.
geo::WireID WireID() const
Initial tdc tick for hit.
Declaration of signal hit object.
static const pandora::Vertex * GetVertex(const pandora::ParticleFlowObject *const pPfo)
Get the pfo vertex.
The data type to uniquely identify a Plane.
Geometry information for a single TPC.
static unsigned int BuildDummySlice(SliceCollection &outputSlices)
Build a new slice object with dummy information.
static void AddAssociation(const art::Event &event, const art::EDProducer *const pProducer, 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.
Settings()
Default constructor.
static void BuildParticleMetadata(const art::Event &event, const art::EDProducer *const pProducer, const std::string &instanceLabel, const pandora::PfoVector &pfoVector, PFParticleMetadataCollection &outputParticleMetadata, PFParticleToMetadataCollection &outputParticlesToMetadata)
Build metadata objects from a list of input pfos.
std::string m_allOutcomesInstanceLabel
The label for the instance producing all outcomes.
std::map< size_t, IdVector > IdToIdVectorMap
Algorithm collection class computing cluster parameters.
static void GetHitsInCluster(const pandora::Cluster *const pCluster, pandora::CaloHitVector &sortedHits)
Collect a sorted list of all 2D hits in a cluster.
Set of hits with a 2D structure.
std::map< int, art::Ptr< recob::Hit > > IdToHitMap
static double CalculateT0(const art::Ptr< recob::Hit > hit, const pandora::CaloHit *const pCaloHit)
Convert X0 correction into T0 correction.
static art::Ptr< recob::Hit > GetHit(const IdToHitMap &idToHitMap, const pandora::CaloHit *const pCaloHit)
Look up ART hit from an input Pandora hit.
bool m_isNeutrinoRecoOnlyNoSlicing
If we are running the neutrino reconstruction only with no slicing.
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...
Helper functions for processing outputs from pandora.
Drift towards negative X values.
std::map< const pandora::CaloHit *, art::Ptr< recob::Hit > > CaloHitToArtHitMap
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
static bool IsFromSlice(const pandora::ParticleFlowObject *const pPfo)
Check if the input pfo is from a slice.
std::unique_ptr< std::vector< recob::SpacePoint > > SpacePointCollection
Definition of vertex object for LArSoft.
static recob::Vertex BuildVertex(const pandora::Vertex *const pVertex, const size_t vertexId)
Convert from a pandora vertex to an ART vertex.
static const SentryArgument_t Sentry
An instance of the sentry object.
std::unique_ptr< std::vector< recob::Slice > > SliceCollection
std::string m_hitfinderModuleLabel
The hit finder module label.
Algorithm collection class computing cluster parameters.
ProductID put(std::unique_ptr< PROD > &&product)
static unsigned int BuildSlice(const pandora::ParticleFlowObject *const pParentPfo, const art::Event &event, const art::EDProducer *const pProducer, 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 void BuildClusters(const art::Event &event, const art::EDProducer *const pProducer, 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::vector< size_t > IdVector
std::unique_ptr< art::Assns< recob::SpacePoint, recob::Hit > > SpacePointToHitCollection
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< Coord_t >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space. See recob::tracking::Coord_t for more details on the ...
Metadata associated to PFParticles.
std::map< int, HitVector > HitArray
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 const pandora::ParticleFlowObject * GetParentPfo(const pandora::ParticleFlowObject *const pPfo)
Get the primary parent pfo.
Header file for the cluster helper class.
static unsigned int GetSliceIndex(const pandora::ParticleFlowObject *const pPfo)
Get the index of the slice from which this pfo was produced.
std::unique_ptr< art::Assns< recob::PFParticle, recob::Slice > > PFParticleToSliceCollection
std::unique_ptr< std::vector< recob::Vertex > > VertexCollection
Helper functions to create a cluster.
static void BuildVertices(const pandora::VertexVector &vertexVector, VertexCollection &outputVertices)
Convert pandora vertices to ART vertices and add them to the output vector.
std::unique_ptr< std::vector< larpandoraobj::PFParticleMetadata > > PFParticleMetadataCollection
static pandora::PfoVector CollectPfos(const pandora::Pandora *const pPrimaryPandora)
Collect the current pfos (including all downstream pfos) from the master pandora instance.
static bool IsClearCosmic(const pandora::ParticleFlowObject *const pPfo)
Check if the input pfo is an unambiguous cosmic ray.
std::unique_ptr< std::vector< recob::PFParticle > > PFParticleCollection
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
Wrapper for ClusterParamsAlgBase objects to accept arbitrary input.
static void ProduceArtOutput(const Settings &settings, const IdToHitMap &idToHitMap, art::Event &evt)
Convert the Pandora PFOs into ART clusters and write into ART event.
Header file for the MultiPandoraApi class.
static bool BuildT0(const pandora::ParticleFlowObject *const pPfo, const pandora::PfoVector &pfoVector, size_t &nextId, const CaloHitToArtHitMap &pandoraHitToArtHitMap, anab::T0 &t0)
If required, build a T0 for the input pfo.
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::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 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< art::Assns< recob::PFParticle, larpandoraobj::PFParticleMetadata > > PFParticleToMetadataCollection
std::vector< art::Ptr< recob::Hit > > HitVector
static void CollectHits(const art::Event &evt, const std::string &label, HitVector &hitVector)
Collect the reconstructed Hits from the ART event record.
Detector simulation of raw signals on wires.
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.
std::unique_ptr< art::Assns< recob::PFParticle, recob::Vertex > > PFParticleToVertexCollection
float PeakTime() const
Time of the signal peak, in tick units.
Hierarchical representation of particle flow.
Utility object to perform functions of association.
std::unique_ptr< std::vector< anab::T0 > > T0Collection
std::unique_ptr< art::Assns< recob::PFParticle, recob::Cluster > > PFParticleToClusterCollection
std::string to_string(Flag_t< Storage > const flag)
Convert a flag into a stream (shows its index).
bool m_shouldRunStitching
const TPCGeo & TPC(unsigned int itpc) const
Return the itpc'th TPC in the cryostat.
bool m_shouldProduceAllOutcomes
If all outcomes should be produced in separate collections (choose false if you only require the cons...
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.
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
static void BuildSlices(const Settings &settings, const pandora::Pandora *const pPrimaryPandora, const art::Event &event, const art::EDProducer *const pProducer, 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< art::Assns< recob::Slice, recob::Hit > > SliceToHitCollection
static void BuildT0s(const art::Event &event, const art::EDProducer *const pProducer, const std::string &instanceLabel, const pandora::PfoVector &pfoVector, T0Collection &outputT0s, const CaloHitToArtHitMap &pandoraHitToArtHitMap, 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::PFParticle, recob::SpacePoint > > PFParticleToSpacePointCollection
Interface to class computing cluster parameters.
virtual void SetHits(std::vector< recob::Hit const * > const &hits)=0
Sets the list of input hits.
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...
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< Coord_t >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space. See recob::tracking::Coord_t for more detai...
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.
recob::Cluster && move()
Prepares the constructed hit to be moved away.
std::set< art::Ptr< recob::Hit > > HitList
static pandora::PfoVector CollectAllPfoOutcomes(const pandora::Pandora *const pPrimaryPandora)
Collect the pfos (including all downstream pfos) from the master and daughter pandora instances...
static void BuildSpacePoints(const art::Event &event, const art::EDProducer *const pProducer, 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 ...
art framework interface to geometry description
std::unique_ptr< art::Assns< recob::Cluster, recob::Hit > > ClusterToHitCollection
cet::coded_exception< error, detail::translate > exception
static larpandoraobj::PFParticleMetadata GetPFParticleMetadata(const pandora::ParticleFlowObject *const pPfo)
Event finding and building.
std::vector< art::Ptr< recob::Vertex > > VertexVector