20 HitType LArClusterHelper::GetClusterHitType(
const Cluster *
const pCluster)
22 if (0 == pCluster->GetNCaloHits())
23 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
29 return (*(pCluster->GetOrderedCaloHitList().begin()->second->begin()))->GetHitType();
34 void LArClusterHelper::GetClustersUVW(
const ClusterList &inputClusters, ClusterList &clusterListU, ClusterList &clusterListV, ClusterList &clusterListW)
38 const HitType hitType(LArClusterHelper::GetClusterHitType(*iter));
40 if (TPC_VIEW_U == hitType) clusterListU.push_back(*iter);
41 else if (TPC_VIEW_V == hitType) clusterListV.push_back(*iter);
42 else if (TPC_VIEW_W == hitType) clusterListW.push_back(*iter);
43 else throw StatusCodeException(STATUS_CODE_NOT_FOUND);
49 void LArClusterHelper::GetClustersByHitType(
const ClusterList &inputClusters,
const HitType hitType, ClusterList &clusterList)
53 if (hitType == LArClusterHelper::GetClusterHitType(*iter))
54 clusterList.push_back(*iter);
60 float LArClusterHelper::GetLengthSquared(
const Cluster *
const pCluster)
62 const OrderedCaloHitList &orderedCaloHitList(pCluster->GetOrderedCaloHitList());
64 if (orderedCaloHitList.empty())
65 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
74 for (
CaloHitList::const_iterator hitIter = iter->second->begin(), hitIterEnd = iter->second->end(); hitIter != hitIterEnd; ++hitIter)
76 const CartesianVector &hitPosition((*hitIter)->GetPositionVector());
77 minX =
std::min(hitPosition.GetX(), minX);
78 maxX =
std::max(hitPosition.GetX(), maxX);
81 minZ =
std::min(hitPosition.GetZ(), minZ);
82 maxZ =
std::max(hitPosition.GetZ(), maxZ);
86 const float deltaX(maxX - minX), deltaY(maxY -
minY), deltaZ(maxZ - minZ);
87 return (deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);
92 float LArClusterHelper::GetLength(
const Cluster *
const pCluster)
94 return std::sqrt(LArClusterHelper::GetLengthSquared(pCluster));
99 float LArClusterHelper::GetEnergyFromLength(
const Cluster *
const pCluster)
101 const float dEdX(0.002
f);
102 return (dEdX * LArClusterHelper::GetLength(pCluster));
107 unsigned int LArClusterHelper::GetLayerSpan(
const Cluster *
const pCluster)
109 return (1 + pCluster->GetOuterPseudoLayer() - pCluster->GetInnerPseudoLayer());
114 float LArClusterHelper::GetLayerOccupancy(
const Cluster *
const pCluster)
116 const unsigned int nOccupiedLayers(pCluster->GetOrderedCaloHitList().size());
117 const unsigned int nLayers(1 + pCluster->GetOuterPseudoLayer() - pCluster->GetInnerPseudoLayer());
120 return (static_cast<float>(nOccupiedLayers) /
static_cast<float>(nLayers));
127 float LArClusterHelper::GetLayerOccupancy(
const Cluster *
const pCluster1,
const Cluster *
const pCluster2)
129 const unsigned int nOccupiedLayers(pCluster1->GetOrderedCaloHitList().size() + pCluster2->GetOrderedCaloHitList().size());
130 const unsigned int nLayers(1 +
std::max(pCluster1->GetOuterPseudoLayer(), pCluster2->GetOuterPseudoLayer()) -
131 std::min(pCluster1->GetInnerPseudoLayer(), pCluster2->GetInnerPseudoLayer()));
134 return (static_cast<float>(nOccupiedLayers) / static_cast<float>(nLayers));
141 float LArClusterHelper::GetClosestDistance(
const ClusterList &clusterList1,
const ClusterList &clusterList2)
143 if (clusterList1.empty() || clusterList2.empty())
144 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
150 const Cluster *
const pCluster1 = *iter1;
151 const float thisDistance(LArClusterHelper::GetClosestDistance(pCluster1, clusterList2));
153 if (thisDistance < closestDistance)
154 closestDistance = thisDistance;
157 return closestDistance;
162 float LArClusterHelper::GetClosestDistance(
const Cluster *
const pCluster,
const ClusterList &clusterList)
164 if (clusterList.empty())
165 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
171 const Cluster *
const pTestCluster = *iter;
172 const float thisDistance(LArClusterHelper::GetClosestDistance(pCluster, pTestCluster));
174 if (thisDistance < closestDistance)
175 closestDistance = thisDistance;
178 return closestDistance;
183 float LArClusterHelper::GetClosestDistance(
const Cluster *
const pCluster1,
const Cluster *
const pCluster2)
185 CartesianVector closestPosition1(0.
f, 0.
f, 0.
f);
186 CartesianVector closestPosition2(0.
f, 0.
f, 0.
f);
188 LArClusterHelper::GetClosestPositions(pCluster1, pCluster2, closestPosition1, closestPosition2);
190 return (closestPosition1 - closestPosition2).GetMagnitude();
195 float LArClusterHelper::GetClosestDistance(
const CartesianVector &position,
const ClusterList &clusterList)
197 return (position - LArClusterHelper::GetClosestPosition(position, clusterList)).GetMagnitude();
202 float LArClusterHelper::GetClosestDistance(
const CartesianVector &position,
const Cluster *
const pCluster)
204 return (position - LArClusterHelper::GetClosestPosition(position, pCluster)).GetMagnitude();
209 CartesianVector LArClusterHelper::GetClosestPosition(
const CartesianVector &position,
const ClusterList &clusterList)
211 bool distanceFound(
false);
213 CartesianVector closestPosition(0.
f, 0.
f, 0.
f);
217 const Cluster *
const pTestCluster = *iter;
218 const CartesianVector thisPosition(LArClusterHelper::GetClosestPosition(position, pTestCluster));
219 const float thisDistanceSquared((position - thisPosition).GetMagnitudeSquared());
221 if (thisDistanceSquared < closestDistanceSquared)
223 distanceFound =
true;
224 closestDistanceSquared = thisDistanceSquared;
225 closestPosition = thisPosition;
230 return closestPosition;
232 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
237 CartesianVector LArClusterHelper::GetClosestPosition(
const CartesianVector &position,
const Cluster *
const pCluster)
239 const OrderedCaloHitList &orderedCaloHitList(pCluster->GetOrderedCaloHitList());
241 const CaloHit *pClosestCaloHit(NULL);
246 for (
CaloHitList::const_iterator hitIter = iter->second->begin(), hitIterEnd = iter->second->end(); hitIter != hitIterEnd; ++hitIter)
248 const CaloHit *
const pCaloHit = *hitIter;
249 const float distanceSquared((pCaloHit->GetPositionVector() - position).GetMagnitudeSquared());
251 if (distanceSquared < closestDistanceSquared)
253 closestDistanceSquared = distanceSquared;
254 pClosestCaloHit = pCaloHit;
260 return pClosestCaloHit->GetPositionVector();
262 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
267 void LArClusterHelper::GetClosestPositions(
const Cluster *
const pCluster1,
const Cluster *
const pCluster2, CartesianVector &outputPosition1,
268 CartesianVector &outputPosition2)
270 bool distanceFound(
false);
273 CartesianVector closestPosition1(0.
f, 0.
f, 0.
f);
274 CartesianVector closestPosition2(0.
f, 0.
f, 0.
f);
276 const OrderedCaloHitList &orderedCaloHitList1(pCluster1->GetOrderedCaloHitList());
277 const OrderedCaloHitList &orderedCaloHitList2(pCluster2->GetOrderedCaloHitList());
282 for (
CaloHitList::const_iterator hitIter1 = iter1->second->begin(), hitIter1End = iter1->second->end(); hitIter1 != hitIter1End; ++hitIter1)
284 const CartesianVector &positionVector1((*hitIter1)->GetPositionVector());
289 for (
CaloHitList::const_iterator hitIter2 = iter2->second->begin(), hitIter2End = iter2->second->end(); hitIter2 != hitIter2End; ++hitIter2)
291 const CartesianVector &positionVector2((*hitIter2)->GetPositionVector());
293 const float distanceSquared((positionVector1 - positionVector2).GetMagnitudeSquared());
295 if (distanceSquared < minDistanceSquared)
297 minDistanceSquared = distanceSquared;
298 closestPosition1 = positionVector1;
299 closestPosition2 = positionVector2;
300 distanceFound =
true;
308 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
310 outputPosition1 = closestPosition1;
311 outputPosition2 = closestPosition2;
316 void LArClusterHelper::GetClusterBoundingBox(
const Cluster *
const pCluster, CartesianVector &minimumCoordinate, CartesianVector &maximumCoordinate)
318 const OrderedCaloHitList &orderedCaloHitList(pCluster->GetOrderedCaloHitList());
331 const CaloHit *
const pCaloHit = *hIter;
332 const CartesianVector &
hit(pCaloHit->GetPositionVector());
342 minimumCoordinate.SetValues(xmin, ymin, zmin);
343 maximumCoordinate.SetValues(xmax, ymax, zmax);
348 void LArClusterHelper::GetClusterSpanX(
const Cluster *
const pCluster,
float &xmin,
float &xmax)
350 const OrderedCaloHitList &orderedCaloHitList(pCluster->GetOrderedCaloHitList());
358 const CaloHit *
const pCaloHit = *hIter;
359 const CartesianVector &
hit(pCaloHit->GetPositionVector());
368 void LArClusterHelper::GetClusterSpanZ(
const Cluster *
const pCluster,
const float xmin,
const float xmax,
369 float &zmin,
float &zmax)
372 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
374 const OrderedCaloHitList &orderedCaloHitList(pCluster->GetOrderedCaloHitList());
379 bool foundHits(
false);
385 const CaloHit *
const pCaloHit = *hIter;
386 const CartesianVector &
hit(pCaloHit->GetPositionVector());
388 if (
hit.GetX() < xmin ||
hit.GetX() > xmax)
398 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
403 StatusCode LArClusterHelper::GetAverageZ(
const Cluster *
const pCluster,
const float xmin,
const float xmax,
float &averageZ)
408 return STATUS_CODE_INVALID_PARAMETER;
410 const OrderedCaloHitList &orderedCaloHitList(pCluster->GetOrderedCaloHitList());
419 const CaloHit *
const pCaloHit = *hIter;
420 const CartesianVector &
hit(pCaloHit->GetPositionVector());
422 if (
hit.GetX() < xmin ||
hit.GetX() > xmax)
431 return STATUS_CODE_NOT_FOUND;
433 averageZ = zsum /
static_cast<float>(count);
434 return STATUS_CODE_SUCCESS;
439 void LArClusterHelper::GetExtremalCoordinates(
const ClusterList &clusterList, CartesianVector &innerCoordinate, CartesianVector &outerCoordinate)
441 OrderedCaloHitList orderedCaloHitList;
445 const Cluster *
const pCluster = *cIter;
446 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, orderedCaloHitList.Add(pCluster->GetOrderedCaloHitList()));
449 return LArClusterHelper::GetExtremalCoordinates(orderedCaloHitList, innerCoordinate, outerCoordinate);
454 void LArClusterHelper::GetExtremalCoordinates(
const Cluster *
const pCluster, CartesianVector &innerCoordinate, CartesianVector &outerCoordinate)
456 return LArClusterHelper::GetExtremalCoordinates(pCluster->GetOrderedCaloHitList(), innerCoordinate, outerCoordinate);
461 void LArClusterHelper::GetExtremalCoordinates(
const OrderedCaloHitList &orderedCaloHitList, CartesianVector &innerCoordinate,
462 CartesianVector &outerCoordinate)
464 if (orderedCaloHitList.empty())
465 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
467 CartesianPointVector coordinateVector;
471 for (
CaloHitList::const_iterator hitIter = iter->second->begin(), hitIterEnd = iter->second->end(); hitIter != hitIterEnd; ++hitIter)
473 const CaloHit *
const pCaloHit = *hitIter;
474 coordinateVector.push_back(pCaloHit->GetPositionVector());
478 std::sort(coordinateVector.begin(), coordinateVector.end(), LArClusterHelper::SortCoordinatesByPosition);
479 return LArClusterHelper::GetExtremalCoordinates(coordinateVector, innerCoordinate, outerCoordinate);
484 void LArClusterHelper::GetExtremalCoordinates(
const CartesianPointVector &coordinateVector, CartesianVector &innerCoordinate,
485 CartesianVector &outerCoordinate)
487 if (coordinateVector.empty())
488 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
500 const CartesianVector &pos = *pIter;
510 const float xAve(0.5
f * (xMin + xMax));
511 const float yAve(0.5
f * (yMin + yMax));
512 const float zAve(0.5
f * (zMin + zMax));
514 const float xSpan(xMax - xMin);
515 const float ySpan(yMax - yMin);
516 const float zSpan(zMax - zMin);
518 const bool useX((xSpan > std::numeric_limits<float>::epsilon()) && (xSpan + std::numeric_limits<float>::epsilon() >
std::max(ySpan, zSpan)));
519 const bool useY((ySpan > std::numeric_limits<float>::epsilon()) && (ySpan + std::numeric_limits<float>::epsilon() >
std::max(zSpan, xSpan)));
520 const bool useZ((zSpan > std::numeric_limits<float>::epsilon()) && (zSpan + std::numeric_limits<float>::epsilon() >
std::max(xSpan, ySpan)));
523 CartesianPointVector candidateVector;
527 const CartesianVector &pos = *pIter;
531 if (((pos.GetX() - xMin) < std::numeric_limits<float>::epsilon()) || ((pos.GetX() - xMax) > -std::numeric_limits<float>::epsilon()))
532 candidateVector.push_back(pos);
537 if (((pos.GetY() - yMin) < std::numeric_limits<float>::epsilon()) || ((pos.GetY() - yMax) > -std::numeric_limits<float>::epsilon()))
538 candidateVector.push_back(pos);
543 if (((pos.GetZ() - zMin) < std::numeric_limits<float>::epsilon()) || ((pos.GetZ() - zMax) > -std::numeric_limits<float>::epsilon()))
544 candidateVector.push_back(pos);
549 CartesianVector firstCoordinate(xAve, yAve, zAve);
550 CartesianVector secondCoordinate(xAve, yAve, zAve);
551 float maxDistanceSquared(+std::numeric_limits<float>::epsilon());
555 const CartesianVector &posI = *iterI;
559 const CartesianVector &posJ = *iterJ;
561 const float distanceSquared((posI - posJ).GetMagnitudeSquared());
563 if (distanceSquared > maxDistanceSquared)
565 maxDistanceSquared = distanceSquared;
566 firstCoordinate = posI;
567 secondCoordinate = posJ;
573 const float deltaZ(secondCoordinate.GetZ() - firstCoordinate.GetZ());
574 const float deltaX(secondCoordinate.GetX() - firstCoordinate.GetX());
576 if ((deltaZ > 0.
f) || ((std::fabs(deltaZ) < std::numeric_limits<float>::epsilon()) && (deltaX > 0.
f)))
578 innerCoordinate = firstCoordinate;
579 outerCoordinate = secondCoordinate;
583 innerCoordinate = secondCoordinate;
584 outerCoordinate = firstCoordinate;
590 void LArClusterHelper::GetCoordinateVector(
const Cluster *
const pCluster, CartesianPointVector &coordinateVector)
592 for (
const OrderedCaloHitList::value_type &layerEntry : pCluster->GetOrderedCaloHitList())
594 for (
const CaloHit *
const pCaloHit : *layerEntry.second)
595 coordinateVector.push_back(pCaloHit->GetPositionVector());
598 std::sort(coordinateVector.begin(), coordinateVector.end(), LArClusterHelper::SortCoordinatesByPosition);
603 bool LArClusterHelper::SortByNOccupiedLayers(
const Cluster *
const pLhs,
const Cluster *
const pRhs)
605 const unsigned int nOccupiedLayersLhs(pLhs->GetOrderedCaloHitList().size());
606 const unsigned int nOccupiedLayersRhs(pRhs->GetOrderedCaloHitList().size());
608 if (nOccupiedLayersLhs != nOccupiedLayersRhs)
609 return (nOccupiedLayersLhs > nOccupiedLayersRhs);
611 return SortByNHits(pLhs, pRhs);
616 bool LArClusterHelper::SortByNHits(
const Cluster *
const pLhs,
const Cluster *
const pRhs)
618 const unsigned int nHitsLhs(pLhs->GetNCaloHits());
619 const unsigned int nHitsRhs(pRhs->GetNCaloHits());
621 if (nHitsLhs != nHitsRhs)
622 return (nHitsLhs > nHitsRhs);
624 return SortByLayerSpan(pLhs, pRhs);
629 bool LArClusterHelper::SortByLayerSpan(
const Cluster *
const pLhs,
const Cluster *
const pRhs)
631 const unsigned int layerSpanLhs(pLhs->GetOuterPseudoLayer() - pLhs->GetInnerPseudoLayer());
632 const unsigned int layerSpanRhs(pRhs->GetOuterPseudoLayer() - pRhs->GetInnerPseudoLayer());
634 if (layerSpanLhs != layerSpanRhs)
635 return (layerSpanLhs > layerSpanRhs);
637 return SortByInnerLayer(pLhs, pRhs);
642 bool LArClusterHelper::SortByInnerLayer(
const Cluster *
const pLhs,
const Cluster *
const pRhs)
644 const unsigned int innerLayerLhs(pLhs->GetInnerPseudoLayer());
645 const unsigned int innerLayerRhs(pRhs->GetInnerPseudoLayer());
647 if (innerLayerLhs != innerLayerRhs)
648 return (innerLayerLhs < innerLayerRhs);
650 return SortByPosition(pLhs, pRhs);
655 bool LArClusterHelper::SortByPosition(
const Cluster *
const pLhs,
const Cluster *
const pRhs)
657 const CartesianVector deltaPositionIL(pRhs->GetCentroid(pRhs->GetInnerPseudoLayer()) - pLhs->GetCentroid(pLhs->GetInnerPseudoLayer()));
659 if (std::fabs(deltaPositionIL.GetZ()) > std::numeric_limits<float>::epsilon())
660 return (deltaPositionIL.GetZ() > std::numeric_limits<float>::epsilon());
662 if (std::fabs(deltaPositionIL.GetX()) > std::numeric_limits<float>::epsilon())
663 return (deltaPositionIL.GetX() > std::numeric_limits<float>::epsilon());
665 if (std::fabs(deltaPositionIL.GetY()) > std::numeric_limits<float>::epsilon())
666 return (deltaPositionIL.GetY() > std::numeric_limits<float>::epsilon());
668 const CartesianVector deltaPositionOL(pRhs->GetCentroid(pRhs->GetOuterPseudoLayer()) - pLhs->GetCentroid(pLhs->GetOuterPseudoLayer()));
670 if (std::fabs(deltaPositionOL.GetZ()) > std::numeric_limits<float>::epsilon())
671 return (deltaPositionOL.GetZ() > std::numeric_limits<float>::epsilon());
673 if (std::fabs(deltaPositionOL.GetX()) > std::numeric_limits<float>::epsilon())
674 return (deltaPositionOL.GetX() > std::numeric_limits<float>::epsilon());
676 if (std::fabs(deltaPositionOL.GetY()) > std::numeric_limits<float>::epsilon())
677 return (deltaPositionOL.GetY() > std::numeric_limits<float>::epsilon());
680 return SortByPulseHeight(pLhs, pRhs);
685 bool LArClusterHelper::SortByPulseHeight(
const Cluster *
const pLhs,
const Cluster *
const pRhs)
687 return (pLhs->GetHadronicEnergy() > pRhs->GetHadronicEnergy());
692 bool LArClusterHelper::SortHitsByPosition(
const CaloHit *
const pLhs,
const CaloHit *
const pRhs)
694 const CartesianVector deltaPosition(pRhs->GetPositionVector() - pLhs->GetPositionVector());
696 if (std::fabs(deltaPosition.GetZ()) > std::numeric_limits<float>::epsilon())
697 return (deltaPosition.GetZ() > std::numeric_limits<float>::epsilon());
699 if (std::fabs(deltaPosition.GetX()) > std::numeric_limits<float>::epsilon())
700 return (deltaPosition.GetX() > std::numeric_limits<float>::epsilon());
702 if (std::fabs(deltaPosition.GetY()) > std::numeric_limits<float>::epsilon())
703 return (deltaPosition.GetY() > std::numeric_limits<float>::epsilon());
706 return SortHitsByPulseHeight(pLhs, pRhs);
711 bool LArClusterHelper::SortHitsByPulseHeight(
const CaloHit *
const pLhs,
const CaloHit *
const pRhs)
714 return (pLhs->GetHadronicEnergy() > pRhs->GetHadronicEnergy());
719 bool LArClusterHelper::SortCoordinatesByPosition(
const CartesianVector &lhs,
const CartesianVector &rhs)
721 const CartesianVector deltaPosition(rhs - lhs);
723 if (std::fabs(deltaPosition.GetZ()) > std::numeric_limits<float>::epsilon())
724 return (deltaPosition.GetZ() > std::numeric_limits<float>::epsilon());
726 if (std::fabs(deltaPosition.GetX()) > std::numeric_limits<float>::epsilon())
727 return (deltaPosition.GetX() > std::numeric_limits<float>::epsilon());
729 return (deltaPosition.GetY() > std::numeric_limits<float>::epsilon());
Header file for the cluster helper class.
Detector simulation of raw signals on wires.