9 #include "Pandora/PdgTable.h" 27 void LArPfoHelper::GetCoordinateVector(
const ParticleFlowObject *
const pPfo,
const HitType &hitType, CartesianPointVector &coordinateVector)
29 ClusterList clusterList;
30 LArPfoHelper::GetClusters(pPfo, hitType, clusterList);
32 for (
const Cluster *
const pCluster : clusterList)
33 LArClusterHelper::GetCoordinateVector(pCluster, coordinateVector);
38 void LArPfoHelper::GetCaloHits(
const PfoList &pfoList,
const HitType &hitType, CaloHitList &caloHitList)
40 for (
const ParticleFlowObject *
const pPfo : pfoList)
41 LArPfoHelper::GetCaloHits(pPfo, hitType, caloHitList);
46 void LArPfoHelper::GetCaloHits(
const ParticleFlowObject *
const pPfo,
const HitType &hitType, CaloHitList &caloHitList)
48 ClusterList clusterList;
49 LArPfoHelper::GetClusters(pPfo, hitType, clusterList);
51 for (
const Cluster *
const pCluster : clusterList)
52 pCluster->GetOrderedCaloHitList().FillCaloHitList(caloHitList);
57 void LArPfoHelper::GetIsolatedCaloHits(
const PfoList &pfoList,
const HitType &hitType, CaloHitList &caloHitList)
59 for (
const ParticleFlowObject *
const pPfo : pfoList)
60 LArPfoHelper::GetIsolatedCaloHits(pPfo, hitType, caloHitList);
65 void LArPfoHelper::GetIsolatedCaloHits(
const ParticleFlowObject *
const pPfo,
const HitType &hitType, CaloHitList &caloHitList)
67 ClusterList clusterList;
68 LArPfoHelper::GetClusters(pPfo, hitType, clusterList);
70 for (
const Cluster *
const pCluster : clusterList)
71 caloHitList.insert(caloHitList.end(), pCluster->GetIsolatedCaloHitList().begin(), pCluster->GetIsolatedCaloHitList().end());
76 void LArPfoHelper::GetClusters(
const PfoList &pfoList,
const HitType &hitType, ClusterList &clusterList)
78 for (
const ParticleFlowObject *
const pPfo : pfoList)
79 LArPfoHelper::GetClusters(pPfo, hitType, clusterList);
84 void LArPfoHelper::GetClusters(
const ParticleFlowObject *
const pPfo,
const HitType &hitType, ClusterList &clusterList)
86 for (
const Cluster *
const pCluster : pPfo->GetClusterList())
88 if (hitType != LArClusterHelper::GetClusterHitType(pCluster))
91 clusterList.push_back(pCluster);
97 void LArPfoHelper::GetTwoDClusterList(
const ParticleFlowObject *
const pPfo, ClusterList &clusterList)
99 for (
const Cluster *
const pCluster : pPfo->GetClusterList())
101 if (TPC_3D == LArClusterHelper::GetClusterHitType(pCluster))
104 clusterList.push_back(pCluster);
110 void LArPfoHelper::GetThreeDClusterList(
const ParticleFlowObject *
const pPfo, ClusterList &clusterList)
112 for (
const Cluster *
const pCluster : pPfo->GetClusterList())
114 if (TPC_3D != LArClusterHelper::GetClusterHitType(pCluster))
117 clusterList.push_back(pCluster);
123 void LArPfoHelper::GetAllConnectedPfos(
const PfoList &inputPfoList, PfoList &outputPfoList)
125 for (
const ParticleFlowObject *
const pPfo : inputPfoList)
126 LArPfoHelper::GetAllConnectedPfos(pPfo, outputPfoList);
131 void LArPfoHelper::GetAllConnectedPfos(
const ParticleFlowObject *
const pPfo, PfoList &outputPfoList)
133 if (outputPfoList.end() != std::find(outputPfoList.begin(), outputPfoList.end(), pPfo))
136 outputPfoList.push_back(pPfo);
137 LArPfoHelper::GetAllConnectedPfos(pPfo->GetParentPfoList(), outputPfoList);
138 LArPfoHelper::GetAllConnectedPfos(pPfo->GetDaughterPfoList(), outputPfoList);
143 void LArPfoHelper::GetAllDownstreamPfos(
const PfoList &inputPfoList, PfoList &outputPfoList)
145 for (
const ParticleFlowObject *
const pPfo : inputPfoList)
146 LArPfoHelper::GetAllDownstreamPfos(pPfo, outputPfoList);
151 void LArPfoHelper::GetAllDownstreamPfos(
const ParticleFlowObject *
const pPfo, PfoList &outputPfoList)
153 if (outputPfoList.end() != std::find(outputPfoList.begin(), outputPfoList.end(), pPfo))
156 outputPfoList.push_back(pPfo);
157 LArPfoHelper::GetAllDownstreamPfos(pPfo->GetDaughterPfoList(), outputPfoList);
162 float LArPfoHelper::GetTwoDLengthSquared(
const ParticleFlowObject *
const pPfo)
164 if (!LArPfoHelper::IsTwoD(pPfo))
165 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
167 float lengthSquared(0.
f);
169 for (
const Cluster *
const pCluster : pPfo->GetClusterList())
171 if (TPC_3D == LArClusterHelper::GetClusterHitType(pCluster))
174 lengthSquared += LArClusterHelper::GetLengthSquared(pCluster);
177 return lengthSquared;
182 float LArPfoHelper::GetThreeDLengthSquared(
const ParticleFlowObject *
const pPfo)
184 if (!LArPfoHelper::IsThreeD(pPfo))
185 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
187 float lengthSquared(0.
f);
189 for (
const Cluster *
const pCluster : pPfo->GetClusterList())
191 if (TPC_3D != LArClusterHelper::GetClusterHitType(pCluster))
194 lengthSquared += LArClusterHelper::GetLengthSquared(pCluster);
197 return lengthSquared;
202 float LArPfoHelper::GetClosestDistance(
const ParticleFlowObject *
const pPfo,
const Cluster *
const pCluster)
204 const HitType hitType(LArClusterHelper::GetClusterHitType(pCluster));
206 ClusterList clusterList;
207 LArPfoHelper::GetClusters(pPfo, hitType, clusterList);
209 if (clusterList.empty())
210 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
214 for (
const Cluster *
const pPfoCluster : clusterList)
216 const float thisDistance(LArClusterHelper::GetClosestDistance(pCluster, pPfoCluster));
218 if (thisDistance < bestDistance)
219 bestDistance = thisDistance;
227 float LArPfoHelper::GetTwoDSeparation(
const ParticleFlowObject *
const pPfo1,
const ParticleFlowObject *
const pPfo2)
229 ClusterList clusterListU1, clusterListV1, clusterListW1;
230 ClusterList clusterListU2, clusterListV2, clusterListW2;
232 LArPfoHelper::GetClusters(pPfo1, TPC_VIEW_U, clusterListU1);
233 LArPfoHelper::GetClusters(pPfo1, TPC_VIEW_V, clusterListV1);
234 LArPfoHelper::GetClusters(pPfo1, TPC_VIEW_W, clusterListW1);
236 LArPfoHelper::GetClusters(pPfo2, TPC_VIEW_U, clusterListU2);
237 LArPfoHelper::GetClusters(pPfo2, TPC_VIEW_V, clusterListV2);
238 LArPfoHelper::GetClusters(pPfo2, TPC_VIEW_W, clusterListW2);
241 float distanceSquared(0.
f);
243 if (!clusterListU1.empty() && !clusterListU2.empty())
245 distanceSquared += LArClusterHelper::GetClosestDistance(clusterListU1, clusterListU2);
249 if (!clusterListV1.empty() && !clusterListV2.empty())
251 distanceSquared += LArClusterHelper::GetClosestDistance(clusterListV1, clusterListV2);
255 if (!clusterListW1.empty() && !clusterListW2.empty())
257 distanceSquared += LArClusterHelper::GetClosestDistance(clusterListW1, clusterListW2);
261 if (numViews < std::numeric_limits<float>::epsilon())
262 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
264 return std::sqrt(distanceSquared / numViews);
269 float LArPfoHelper::GetThreeDSeparation(
const ParticleFlowObject *
const pPfo1,
const ParticleFlowObject *
const pPfo2)
271 ClusterList clusterList1, clusterList2;
273 LArPfoHelper::GetClusters(pPfo1, TPC_3D, clusterList1);
274 LArPfoHelper::GetClusters(pPfo2, TPC_3D, clusterList2);
276 if (clusterList1.empty() || clusterList2.empty())
277 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
279 return LArClusterHelper::GetClosestDistance(clusterList1, clusterList2);
284 bool LArPfoHelper::IsTwoD(
const ParticleFlowObject *
const pPfo)
286 for (
const Cluster *
const pCluster : pPfo->GetClusterList())
288 if (TPC_3D != LArClusterHelper::GetClusterHitType(pCluster))
297 bool LArPfoHelper::IsThreeD(
const ParticleFlowObject *
const pPfo)
299 for (
const Cluster *
const pCluster : pPfo->GetClusterList())
301 if (TPC_3D == LArClusterHelper::GetClusterHitType(pCluster))
310 bool LArPfoHelper::IsTrack(
const ParticleFlowObject *
const pPfo)
312 const int pdg(pPfo->GetParticleId());
315 return ((MU_MINUS == std::abs(pdg)) || (PI_PLUS == std::abs(pdg)) || (PROTON == std::abs(pdg)) || (K_PLUS == std::abs(pdg)));
320 bool LArPfoHelper::IsShower(
const ParticleFlowObject *
const pPfo)
322 const int pdg(pPfo->GetParticleId());
325 return ((E_MINUS == std::abs(pdg)) || (PHOTON == std::abs(pdg)));
330 int LArPfoHelper::GetPrimaryNeutrino(
const ParticleFlowObject *
const pPfo)
334 const ParticleFlowObject *
const pParentPfo = LArPfoHelper::GetParentNeutrino(pPfo);
335 return pParentPfo->GetParticleId();
337 catch (
const StatusCodeException &)
345 bool LArPfoHelper::IsFinalState(
const ParticleFlowObject *
const pPfo)
347 if (pPfo->GetParentPfoList().empty() && !LArPfoHelper::IsNeutrino(pPfo))
350 if (LArPfoHelper::IsNeutrinoFinalState(pPfo))
358 bool LArPfoHelper::IsNeutrinoFinalState(
const ParticleFlowObject *
const pPfo)
360 return ((pPfo->GetParentPfoList().size() == 1) && (LArPfoHelper::IsNeutrino(*(pPfo->GetParentPfoList().begin()))));
365 bool LArPfoHelper::IsNeutrino(
const ParticleFlowObject *
const pPfo)
367 const int absoluteParticleId(std::abs(pPfo->GetParticleId()));
369 if ((NU_E == absoluteParticleId) || (NU_MU == absoluteParticleId) || (NU_TAU == absoluteParticleId))
377 bool LArPfoHelper::IsTestBeam(
const ParticleFlowObject *
const pPfo)
379 const PropertiesMap &properties(pPfo->GetPropertiesMap());
382 if (iter != properties.end())
383 return ((iter->second > 0.f) ?
true :
false);
390 void LArPfoHelper::GetRecoNeutrinos(
const PfoList *
const pPfoList, PfoList &recoNeutrinos)
395 for (
const ParticleFlowObject *
const pPfo : *pPfoList)
397 if (LArPfoHelper::IsNeutrino(pPfo))
398 recoNeutrinos.push_back(pPfo);
404 const ParticleFlowObject *LArPfoHelper::GetParentPfo(
const ParticleFlowObject *
const pPfo)
406 const ParticleFlowObject *pParentPfo = pPfo;
408 while (pParentPfo->GetParentPfoList().empty() ==
false)
410 pParentPfo = *(pParentPfo->GetParentPfoList().begin());
418 const ParticleFlowObject *LArPfoHelper::GetParentNeutrino(
const ParticleFlowObject *
const pPfo)
420 const ParticleFlowObject *
const pParentPfo = LArPfoHelper::GetParentPfo(pPfo);
422 if(!LArPfoHelper::IsNeutrino(pParentPfo))
423 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
430 const Vertex *LArPfoHelper::GetVertex(
const ParticleFlowObject *
const pPfo)
432 if (pPfo->GetVertexList().empty())
433 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
435 if (pPfo->GetVertexList().size() != 1)
436 throw StatusCodeException(STATUS_CODE_FAILURE);
438 const Vertex *
const pVertex = *(pPfo->GetVertexList().begin());
440 if (VERTEX_3D != pVertex->GetVertexType())
441 throw StatusCodeException(STATUS_CODE_FAILURE);
448 void LArPfoHelper::GetSlidingFitTrajectory(
const CartesianPointVector &pointVector,
const CartesianVector &vertexPosition,
451 LArPfoHelper::SlidingFitTrajectoryImpl(&pointVector, vertexPosition, layerWindow, layerPitch, trackStateVector, pIndexVector);
456 void LArPfoHelper::GetSlidingFitTrajectory(
const ParticleFlowObject *
const pPfo,
const Vertex *
const pVertex,
457 const unsigned int layerWindow,
const float layerPitch,
LArTrackStateVector &trackStateVector)
459 CaloHitList caloHitList;
460 LArPfoHelper::GetCaloHits(pPfo, TPC_3D, caloHitList);
461 LArPfoHelper::SlidingFitTrajectoryImpl(&caloHitList, pVertex->GetPosition(), layerWindow, layerPitch, trackStateVector);
466 LArShowerPCA LArPfoHelper::GetPrincipalComponents(
const CartesianPointVector &pointVector,
const CartesianVector &vertexPosition)
469 CartesianVector centroid(0.
f, 0.
f, 0.
f);
472 LArPcaHelper::RunPca(pointVector, centroid, eigenValues, eigenVecs);
475 if (eigenValues.GetX() < std::numeric_limits<float>::epsilon())
476 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
479 const float testProjection(eigenVecs.at(0).GetDotProduct(vertexPosition - centroid));
480 const float directionScaleFactor((testProjection > std::numeric_limits<float>::epsilon()) ? -1.
f : 1.
f);
482 const CartesianVector primaryAxis(eigenVecs.at(0) * directionScaleFactor);
483 const CartesianVector secondaryAxis(eigenVecs.at(1) * directionScaleFactor);
484 const CartesianVector tertiaryAxis(eigenVecs.at(2) * directionScaleFactor);
486 return LArShowerPCA(centroid, primaryAxis, secondaryAxis, tertiaryAxis, eigenValues);
491 LArShowerPCA LArPfoHelper::GetPrincipalComponents(
const ParticleFlowObject *
const pPfo,
const Vertex *
const pVertex)
493 CartesianPointVector pointVector;
494 LArPfoHelper::GetCoordinateVector(pPfo, TPC_3D, pointVector);
495 return LArPfoHelper::GetPrincipalComponents(pointVector, pVertex->GetPosition());
502 if (lhs.first != rhs.first)
503 return (lhs.first < rhs.first);
509 const float dx(lhs.second.GetPosition().GetX() - rhs.second.GetPosition().GetX());
510 const float dy(lhs.second.GetPosition().GetY() - rhs.second.GetPosition().GetY());
511 const float dz(lhs.second.GetPosition().GetZ() - rhs.second.GetPosition().GetZ());
512 return (dx + dy + dz > 0.
f);
517 bool LArPfoHelper::SortByNHits(
const ParticleFlowObject *
const pLhs,
const ParticleFlowObject *
const pRhs)
519 unsigned int nTwoDHitsLhs(0), nThreeDHitsLhs(0);
float energyLhs(0.
f);
520 for (
ClusterList::const_iterator iter = pLhs->GetClusterList().begin(), iterEnd = pLhs->GetClusterList().end(); iter != iterEnd; ++iter)
522 const Cluster *
const pClusterLhs = *iter;
524 if (TPC_3D != LArClusterHelper::GetClusterHitType(pClusterLhs))
525 nTwoDHitsLhs += pClusterLhs->GetNCaloHits();
527 nThreeDHitsLhs += pClusterLhs->GetNCaloHits();
529 energyLhs += pClusterLhs->GetHadronicEnergy();
532 unsigned int nTwoDHitsRhs(0), nThreeDHitsRhs(0);
float energyRhs(0.
f);
533 for (
ClusterList::const_iterator iter = pRhs->GetClusterList().begin(), iterEnd = pRhs->GetClusterList().end(); iter != iterEnd; ++iter)
535 const Cluster *
const pClusterRhs = *iter;
537 if (TPC_3D != LArClusterHelper::GetClusterHitType(pClusterRhs))
538 nTwoDHitsRhs += pClusterRhs->GetNCaloHits();
540 nThreeDHitsRhs += pClusterRhs->GetNCaloHits();
542 energyRhs += pClusterRhs->GetHadronicEnergy();
545 if (nTwoDHitsLhs != nTwoDHitsRhs)
546 return (nTwoDHitsLhs > nTwoDHitsRhs);
548 if (nThreeDHitsLhs != nThreeDHitsRhs)
549 return (nThreeDHitsLhs > nThreeDHitsRhs);
552 return (energyLhs > energyRhs);
557 template <
typename T>
558 void LArPfoHelper::SlidingFitTrajectoryImpl(
const T *
const pT,
const CartesianVector &vertexPosition,
const unsigned int layerWindow,
561 CartesianPointVector pointVector;
563 for (
const auto &nextPoint : *pT)
564 pointVector.push_back(LArObjectHelper::TypeAdaptor::GetPosition(nextPoint));
566 if (pointVector.empty())
567 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
569 std::sort(pointVector.begin(), pointVector.end(), LArClusterHelper::SortCoordinatesByPosition);
573 if (pIndexVector) pIndexVector->clear();
581 if ((maxPosition - minPosition).GetMagnitudeSquared() < std::numeric_limits<float>::epsilon())
582 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
584 const CartesianVector seedPosition((maxPosition + minPosition) * 0.5
f);
585 const CartesianVector seedDirection((maxPosition - minPosition).GetUnitVector());
587 const float scaleFactor((seedDirection.GetDotProduct(seedPosition - vertexPosition) > 0.f) ? +1.f : -1.f);
590 for (
const auto &nextPoint : *pT)
598 CartesianVector position(0.f, 0.f, 0.f);
601 if (positionStatusCode != STATUS_CODE_SUCCESS)
602 throw StatusCodeException(positionStatusCode);
604 CartesianVector direction(0.f, 0.f, 0.f);
607 if (directionStatusCode != STATUS_CODE_SUCCESS)
608 throw StatusCodeException(directionStatusCode);
610 const float projection(seedDirection.GetDotProduct(position - seedPosition));
613 LArTrackState(position, direction * scaleFactor, LArObjectHelper::TypeAdaptor::GetCaloHit(nextPoint)), index));
615 catch (
const StatusCodeException &statusCodeException1)
617 indicesWithoutSpacePoints.push_back(index);
619 if (STATUS_CODE_FAILURE == statusCodeException1.GetStatusCode())
620 throw statusCodeException1;
624 catch (
const StatusCodeException &statusCodeException2)
626 if (STATUS_CODE_FAILURE == statusCodeException2.GetStatusCode())
627 throw statusCodeException2;
631 std::sort(trackTrajectory.begin(), trackTrajectory.end(), LArPfoHelper::SortByHitProjection);
635 trackStateVector.push_back(larTrackTrajectoryPoint.second);
636 if (pIndexVector) pIndexVector->push_back(larTrackTrajectoryPoint.GetIndex());
642 for (
const int index : indicesWithoutSpacePoints)
643 pIndexVector->push_back(index);
649 template void LArPfoHelper::SlidingFitTrajectoryImpl(
const CartesianPointVector *
const,
const CartesianVector &,
const unsigned int,
const float,
LArTrackStateVector &,
IntVector *
const);
650 template void LArPfoHelper::SlidingFitTrajectoryImpl(
const CaloHitList *
const,
const CartesianVector &,
const unsigned int,
const float,
LArTrackStateVector &,
IntVector *
const);
Header file for the pfo helper class.
pandora::CartesianVector EigenValues
Header file for the principal curve analysis helper class.
std::vector< int > IntVector
float GetLongitudinalDisplacement(const pandora::CartesianVector &position) const
Get longitudinal projection onto primary axis.
std::vector< LArTrackTrajectoryPoint > LArTrackTrajectory
Header file for the object helper class.
Header file for the cluster helper class.
pandora::StatusCode GetGlobalFitDirection(const float rL, pandora::CartesianVector &direction) const
Get global fit direction for a given longitudinal coordinate.
const pandora::CartesianVector & GetGlobalMaxLayerPosition() const
Get global position corresponding to the fit result in maximum fit layer.
Header file for the lar three dimensional sliding fit result class.
std::vector< pandora::CartesianVector > EigenVectors
ThreeDSlidingFitResult class.
std::vector< LArTrackState > LArTrackStateVector
LArTrackTrajectoryPoint class.
pandora::StatusCode GetGlobalFitPosition(const float rL, pandora::CartesianVector &position) const
Get global fit position for a given longitudinal coordinate.
const pandora::CartesianVector & GetGlobalMinLayerPosition() const
Get global position corresponding to the fit result in minimum fit layer.