21 HitType LArClusterHelper::GetClusterHitType(
const Cluster *
const pCluster)
23 if (0 == pCluster->GetNCaloHits())
24 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
30 return (*(pCluster->GetOrderedCaloHitList().begin()->second->begin()))->GetHitType();
35 void LArClusterHelper::GetClustersUVW(
const ClusterList &inputClusters, ClusterList &clusterListU, ClusterList &clusterListV, ClusterList &clusterListW)
39 const HitType hitType(LArClusterHelper::GetClusterHitType(*iter));
41 if (TPC_VIEW_U == hitType)
42 clusterListU.push_back(*iter);
43 else if (TPC_VIEW_V == hitType)
44 clusterListV.push_back(*iter);
45 else if (TPC_VIEW_W == hitType)
46 clusterListW.push_back(*iter);
48 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
54 void LArClusterHelper::GetClustersByHitType(
const ClusterList &inputClusters,
const HitType hitType, ClusterList &clusterList)
58 if (hitType == LArClusterHelper::GetClusterHitType(*iter))
59 clusterList.push_back(*iter);
65 float LArClusterHelper::GetLengthSquared(
const Cluster *
const pCluster)
67 const OrderedCaloHitList &orderedCaloHitList(pCluster->GetOrderedCaloHitList());
69 if (orderedCaloHitList.empty())
70 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
79 for (
CaloHitList::const_iterator hitIter = iter->second->begin(), hitIterEnd = iter->second->end(); hitIter != hitIterEnd; ++hitIter)
81 const CartesianVector &hitPosition((*hitIter)->GetPositionVector());
82 minX =
std::min(hitPosition.GetX(), minX);
83 maxX =
std::max(hitPosition.GetX(), maxX);
84 minY =
std::min(hitPosition.GetY(), minY);
85 maxY =
std::max(hitPosition.GetY(), maxY);
86 minZ =
std::min(hitPosition.GetZ(), minZ);
87 maxZ =
std::max(hitPosition.GetZ(), maxZ);
91 const float deltaX(maxX - minX), deltaY(maxY - minY), deltaZ(maxZ - minZ);
92 return (deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);
97 float LArClusterHelper::GetLength(
const Cluster *
const pCluster)
99 return std::sqrt(LArClusterHelper::GetLengthSquared(pCluster));
104 float LArClusterHelper::GetEnergyFromLength(
const Cluster *
const pCluster)
106 const float dEdX(0.002
f);
107 return (dEdX * LArClusterHelper::GetLength(pCluster));
112 unsigned int LArClusterHelper::GetLayerSpan(
const Cluster *
const pCluster)
114 return (1 + pCluster->GetOuterPseudoLayer() - pCluster->GetInnerPseudoLayer());
119 float LArClusterHelper::GetLayerOccupancy(
const Cluster *
const pCluster)
121 const unsigned int nOccupiedLayers(pCluster->GetOrderedCaloHitList().size());
122 const unsigned int nLayers(1 + pCluster->GetOuterPseudoLayer() - pCluster->GetInnerPseudoLayer());
125 return (static_cast<float>(nOccupiedLayers) /
static_cast<float>(nLayers));
132 float LArClusterHelper::GetLayerOccupancy(
const Cluster *
const pCluster1,
const Cluster *
const pCluster2)
134 const unsigned int nOccupiedLayers(pCluster1->GetOrderedCaloHitList().size() + pCluster2->GetOrderedCaloHitList().size());
135 const unsigned int nLayers(1 +
std::max(pCluster1->GetOuterPseudoLayer(), pCluster2->GetOuterPseudoLayer()) -
136 std::min(pCluster1->GetInnerPseudoLayer(), pCluster2->GetInnerPseudoLayer()));
139 return (static_cast<float>(nOccupiedLayers) / static_cast<float>(nLayers));
146 float LArClusterHelper::GetClosestDistance(
const ClusterList &clusterList1,
const ClusterList &clusterList2)
148 if (clusterList1.empty() || clusterList2.empty())
149 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
155 const Cluster *
const pCluster1 = *iter1;
156 const float thisDistance(LArClusterHelper::GetClosestDistance(pCluster1, clusterList2));
158 if (thisDistance < closestDistance)
159 closestDistance = thisDistance;
162 return closestDistance;
167 float LArClusterHelper::GetClosestDistance(
const Cluster *
const pCluster,
const ClusterList &clusterList)
169 if (clusterList.empty())
170 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
176 const Cluster *
const pTestCluster = *iter;
177 const float thisDistance(LArClusterHelper::GetClosestDistance(pCluster, pTestCluster));
179 if (thisDistance < closestDistance)
180 closestDistance = thisDistance;
183 return closestDistance;
188 float LArClusterHelper::GetClosestDistance(
const Cluster *
const pCluster1,
const Cluster *
const pCluster2)
190 CartesianVector closestPosition1(0.
f, 0.
f, 0.
f);
191 CartesianVector closestPosition2(0.
f, 0.
f, 0.
f);
193 LArClusterHelper::GetClosestPositions(pCluster1, pCluster2, closestPosition1, closestPosition2);
195 return (closestPosition1 - closestPosition2).GetMagnitude();
200 float LArClusterHelper::GetClosestDistance(
const CartesianVector &
position,
const ClusterList &clusterList)
202 return (position - LArClusterHelper::GetClosestPosition(position, clusterList)).GetMagnitude();
207 float LArClusterHelper::GetClosestDistance(
const CartesianVector &position,
const Cluster *
const pCluster)
209 return (position - LArClusterHelper::GetClosestPosition(position, pCluster)).GetMagnitude();
214 float LArClusterHelper::GetClosestDistance(
const CartesianVector &position,
const CaloHitList &caloHitList)
216 return (position - LArClusterHelper::GetClosestPosition(position, caloHitList)).GetMagnitude();
221 CartesianVector LArClusterHelper::GetClosestPosition(
const CartesianVector &position,
const ClusterList &clusterList)
223 bool distanceFound(
false);
225 CartesianVector closestPosition(0.
f, 0.
f, 0.
f);
229 const Cluster *
const pTestCluster = *iter;
230 const CartesianVector thisPosition(LArClusterHelper::GetClosestPosition(position, pTestCluster));
231 const float thisDistanceSquared((position - thisPosition).GetMagnitudeSquared());
233 if (thisDistanceSquared < closestDistanceSquared)
235 distanceFound =
true;
236 closestDistanceSquared = thisDistanceSquared;
237 closestPosition = thisPosition;
242 return closestPosition;
244 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
249 CartesianVector LArClusterHelper::GetClosestPosition(
const CartesianVector &position,
const Cluster *
const pCluster)
251 CaloHitList caloHitList;
252 pCluster->GetOrderedCaloHitList().FillCaloHitList(caloHitList);
254 return LArClusterHelper::GetClosestPosition(position, caloHitList);
259 CartesianVector LArClusterHelper::GetClosestPosition(
const CartesianVector &position,
const CaloHitList &caloHitList)
261 const CaloHit *pClosestCaloHit(
nullptr);
264 for (
const CaloHit *
const pCaloHit : caloHitList)
266 const float distanceSquared((pCaloHit->GetPositionVector() -
position).GetMagnitudeSquared());
268 if (distanceSquared < closestDistanceSquared)
270 closestDistanceSquared = distanceSquared;
271 pClosestCaloHit = pCaloHit;
276 return pClosestCaloHit->GetPositionVector();
278 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
283 void LArClusterHelper::GetClosestPositions(
284 const Cluster *
const pCluster1,
const Cluster *
const pCluster2, CartesianVector &outputPosition1, CartesianVector &outputPosition2)
286 bool distanceFound(
false);
289 CartesianVector closestPosition1(0.
f, 0.
f, 0.
f);
290 CartesianVector closestPosition2(0.
f, 0.
f, 0.
f);
292 const OrderedCaloHitList &orderedCaloHitList1(pCluster1->GetOrderedCaloHitList());
293 const OrderedCaloHitList &orderedCaloHitList2(pCluster2->GetOrderedCaloHitList());
298 for (
CaloHitList::const_iterator hitIter1 = iter1->second->begin(), hitIter1End = iter1->second->end(); hitIter1 != hitIter1End; ++hitIter1)
300 const CartesianVector &positionVector1((*hitIter1)->GetPositionVector());
305 for (
CaloHitList::const_iterator hitIter2 = iter2->second->begin(), hitIter2End = iter2->second->end(); hitIter2 != hitIter2End; ++hitIter2)
307 const CartesianVector &positionVector2((*hitIter2)->GetPositionVector());
309 const float distanceSquared((positionVector1 - positionVector2).GetMagnitudeSquared());
311 if (distanceSquared < minDistanceSquared)
313 minDistanceSquared = distanceSquared;
314 closestPosition1 = positionVector1;
315 closestPosition2 = positionVector2;
316 distanceFound =
true;
324 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
326 outputPosition1 = closestPosition1;
327 outputPosition2 = closestPosition2;
332 void LArClusterHelper::GetClusterBoundingBox(
const Cluster *
const pCluster, CartesianVector &minimumCoordinate, CartesianVector &maximumCoordinate)
334 const OrderedCaloHitList &orderedCaloHitList(pCluster->GetOrderedCaloHitList());
347 const CaloHit *
const pCaloHit = *hIter;
348 const CartesianVector &
hit(pCaloHit->GetPositionVector());
358 minimumCoordinate.SetValues(xmin, ymin, zmin);
359 maximumCoordinate.SetValues(xmax, ymax, zmax);
364 StatusCode LArClusterHelper::GetAverageZ(
const Cluster *
const pCluster,
const float xmin,
const float xmax,
float &averageZ)
369 return STATUS_CODE_INVALID_PARAMETER;
371 const OrderedCaloHitList &orderedCaloHitList(pCluster->GetOrderedCaloHitList());
380 const CaloHit *
const pCaloHit = *hIter;
381 const CartesianVector &
hit(pCaloHit->GetPositionVector());
383 if (
hit.GetX() < xmin ||
hit.GetX() > xmax)
392 return STATUS_CODE_NOT_FOUND;
394 averageZ = zsum /
static_cast<float>(
count);
395 return STATUS_CODE_SUCCESS;
400 void LArClusterHelper::GetExtremalCoordinates(
const ClusterList &clusterList, CartesianVector &innerCoordinate, CartesianVector &outerCoordinate)
402 OrderedCaloHitList orderedCaloHitList;
406 const Cluster *
const pCluster = *cIter;
407 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, orderedCaloHitList.Add(pCluster->GetOrderedCaloHitList()));
410 return LArClusterHelper::GetExtremalCoordinates(orderedCaloHitList, innerCoordinate, outerCoordinate);
415 void LArClusterHelper::GetExtremalCoordinates(
const Cluster *
const pCluster, CartesianVector &innerCoordinate, CartesianVector &outerCoordinate)
417 return LArClusterHelper::GetExtremalCoordinates(pCluster->GetOrderedCaloHitList(), innerCoordinate, outerCoordinate);
422 void LArClusterHelper::GetExtremalCoordinates(
const OrderedCaloHitList &orderedCaloHitList, CartesianVector &innerCoordinate, CartesianVector &outerCoordinate)
424 if (orderedCaloHitList.empty())
425 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
427 CartesianPointVector coordinateVector;
431 for (
CaloHitList::const_iterator hitIter = iter->second->begin(), hitIterEnd = iter->second->end(); hitIter != hitIterEnd; ++hitIter)
433 const CaloHit *
const pCaloHit = *hitIter;
434 coordinateVector.push_back(pCaloHit->GetPositionVector());
438 std::sort(coordinateVector.begin(), coordinateVector.end(), LArClusterHelper::SortCoordinatesByPosition);
439 return LArClusterHelper::GetExtremalCoordinates(coordinateVector, innerCoordinate, outerCoordinate);
444 void LArClusterHelper::GetExtremalCoordinates(
const CartesianPointVector &coordinateVector, CartesianVector &innerCoordinate, CartesianVector &outerCoordinate)
446 if (coordinateVector.empty())
447 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
459 const CartesianVector &
pos = *pIter;
469 const float xAve(0.5
f * (xMin + xMax));
470 const float yAve(0.5
f * (yMin + yMax));
471 const float zAve(0.5
f * (zMin + zMax));
473 const float xSpan(xMax - xMin);
474 const float ySpan(yMax - yMin);
475 const float zSpan(zMax - zMin);
477 const bool useX((xSpan > std::numeric_limits<float>::epsilon()) && (xSpan + std::numeric_limits<float>::epsilon() >
std::max(ySpan, zSpan)));
478 const bool useY((ySpan > std::numeric_limits<float>::epsilon()) && (ySpan + std::numeric_limits<float>::epsilon() >
std::max(zSpan, xSpan)));
479 const bool useZ((zSpan > std::numeric_limits<float>::epsilon()) && (zSpan + std::numeric_limits<float>::epsilon() >
std::max(xSpan, ySpan)));
482 CartesianPointVector candidateVector;
486 const CartesianVector &
pos = *pIter;
490 if (((pos.GetX() - xMin) < std::numeric_limits<float>::epsilon()) || ((pos.GetX() - xMax) > -std::numeric_limits<float>::epsilon()))
491 candidateVector.push_back(pos);
496 if (((pos.GetY() - yMin) < std::numeric_limits<float>::epsilon()) || ((pos.GetY() - yMax) > -std::numeric_limits<float>::epsilon()))
497 candidateVector.push_back(pos);
502 if (((pos.GetZ() - zMin) < std::numeric_limits<float>::epsilon()) || ((pos.GetZ() - zMax) > -std::numeric_limits<float>::epsilon()))
503 candidateVector.push_back(pos);
508 CartesianVector firstCoordinate(xAve, yAve, zAve);
509 CartesianVector secondCoordinate(xAve, yAve, zAve);
510 float maxDistanceSquared(+std::numeric_limits<float>::epsilon());
514 const CartesianVector &posI = *iterI;
518 const CartesianVector &posJ = *iterJ;
520 const float distanceSquared((posI - posJ).GetMagnitudeSquared());
522 if (distanceSquared > maxDistanceSquared)
524 maxDistanceSquared = distanceSquared;
525 firstCoordinate = posI;
526 secondCoordinate = posJ;
532 const float deltaZ(secondCoordinate.GetZ() - firstCoordinate.GetZ());
533 const float deltaX(secondCoordinate.GetX() - firstCoordinate.GetX());
535 if ((deltaZ > 0.
f) || ((std::fabs(deltaZ) < std::numeric_limits<float>::epsilon()) && (deltaX > 0.
f)))
537 innerCoordinate = firstCoordinate;
538 outerCoordinate = secondCoordinate;
542 innerCoordinate = secondCoordinate;
543 outerCoordinate = firstCoordinate;
549 void LArClusterHelper::GetCoordinateVector(
const Cluster *
const pCluster, CartesianPointVector &coordinateVector)
551 for (
const OrderedCaloHitList::value_type &layerEntry : pCluster->GetOrderedCaloHitList())
553 for (
const CaloHit *
const pCaloHit : *layerEntry.second)
554 coordinateVector.push_back(pCaloHit->GetPositionVector());
557 std::sort(coordinateVector.begin(), coordinateVector.end(), LArClusterHelper::SortCoordinatesByPosition);
562 void LArClusterHelper::GetCaloHitListInBoundingBox(
const pandora::Cluster *
const pCluster,
const pandora::CartesianVector &lowerBound,
563 const pandora::CartesianVector &upperBound, pandora::CaloHitList &caloHitList)
565 const bool useX(std::fabs(upperBound.GetX() - lowerBound.GetX()) > std::numeric_limits<float>::epsilon());
566 const bool useY(std::fabs(upperBound.GetY() - lowerBound.GetY()) > std::numeric_limits<float>::epsilon());
567 const bool useZ(std::fabs(upperBound.GetZ() - lowerBound.GetZ()) > std::numeric_limits<float>::epsilon());
568 if (!useX && !useY && !useZ)
569 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
571 const float minX(
std::min(lowerBound.GetX(), upperBound.GetX()));
572 const float maxX(
std::max(lowerBound.GetX(), upperBound.GetX()));
573 const float minY(
std::min(lowerBound.GetY(), upperBound.GetY()));
574 const float maxY(
std::max(lowerBound.GetY(), upperBound.GetY()));
575 const float minZ(
std::min(lowerBound.GetZ(), upperBound.GetZ()));
576 const float maxZ(
std::max(lowerBound.GetZ(), upperBound.GetZ()));
578 for (
const OrderedCaloHitList::value_type &layerEntry : pCluster->GetOrderedCaloHitList())
580 for (
const CaloHit *
const pCaloHit : *layerEntry.second)
582 const CartesianVector &hitPosition = pCaloHit->GetPositionVector();
583 if (useX && (hitPosition.GetX() < minX - std::numeric_limits<float>::epsilon() ||
584 hitPosition.GetX() > maxX + std::numeric_limits<float>::epsilon()))
586 else if (useY && (hitPosition.GetY() < minY - std::numeric_limits<float>::epsilon() ||
587 hitPosition.GetY() > maxY + std::numeric_limits<float>::epsilon()))
589 else if (useZ && (hitPosition.GetZ() < minZ - std::numeric_limits<float>::epsilon() ||
590 hitPosition.GetZ() > maxZ + std::numeric_limits<float>::epsilon()))
593 caloHitList.push_back(pCaloHit);
596 caloHitList.sort(LArClusterHelper::SortHitsByPosition);
601 void LArClusterHelper::GetDaughterVolumeIDs(
const Cluster *
const pCluster,
UIntSet &daughterVolumeIds)
603 const OrderedCaloHitList &orderedCaloHitList(pCluster->GetOrderedCaloHitList());
609 const CaloHit *
const pCaloHit(*hIter);
610 const LArCaloHit *
const pLArCaloHit(dynamic_cast<const LArCaloHit *>(pCaloHit));
619 bool LArClusterHelper::SortByNOccupiedLayers(
const Cluster *
const pLhs,
const Cluster *
const pRhs)
621 const unsigned int nOccupiedLayersLhs(pLhs->GetOrderedCaloHitList().size());
622 const unsigned int nOccupiedLayersRhs(pRhs->GetOrderedCaloHitList().size());
624 if (nOccupiedLayersLhs != nOccupiedLayersRhs)
625 return (nOccupiedLayersLhs > nOccupiedLayersRhs);
627 return SortByNHits(pLhs, pRhs);
632 bool LArClusterHelper::SortByNHits(
const Cluster *
const pLhs,
const Cluster *
const pRhs)
634 const unsigned int nHitsLhs(pLhs->GetNCaloHits());
635 const unsigned int nHitsRhs(pRhs->GetNCaloHits());
637 if (nHitsLhs != nHitsRhs)
638 return (nHitsLhs > nHitsRhs);
640 return SortByLayerSpan(pLhs, pRhs);
645 bool LArClusterHelper::SortByLayerSpan(
const Cluster *
const pLhs,
const Cluster *
const pRhs)
647 const unsigned int layerSpanLhs(pLhs->GetOuterPseudoLayer() - pLhs->GetInnerPseudoLayer());
648 const unsigned int layerSpanRhs(pRhs->GetOuterPseudoLayer() - pRhs->GetInnerPseudoLayer());
650 if (layerSpanLhs != layerSpanRhs)
651 return (layerSpanLhs > layerSpanRhs);
653 return SortByInnerLayer(pLhs, pRhs);
658 bool LArClusterHelper::SortByInnerLayer(
const Cluster *
const pLhs,
const Cluster *
const pRhs)
660 const unsigned int innerLayerLhs(pLhs->GetInnerPseudoLayer());
661 const unsigned int innerLayerRhs(pRhs->GetInnerPseudoLayer());
663 if (innerLayerLhs != innerLayerRhs)
664 return (innerLayerLhs < innerLayerRhs);
666 return SortByPosition(pLhs, pRhs);
671 bool LArClusterHelper::SortByPosition(
const Cluster *
const pLhs,
const Cluster *
const pRhs)
673 const CartesianVector deltaPositionIL(pRhs->GetCentroid(pRhs->GetInnerPseudoLayer()) - pLhs->GetCentroid(pLhs->GetInnerPseudoLayer()));
675 if (std::fabs(deltaPositionIL.GetZ()) > std::numeric_limits<float>::epsilon())
676 return (deltaPositionIL.GetZ() > std::numeric_limits<float>::epsilon());
678 if (std::fabs(deltaPositionIL.GetX()) > std::numeric_limits<float>::epsilon())
679 return (deltaPositionIL.GetX() > std::numeric_limits<float>::epsilon());
681 if (std::fabs(deltaPositionIL.GetY()) > std::numeric_limits<float>::epsilon())
682 return (deltaPositionIL.GetY() > std::numeric_limits<float>::epsilon());
684 const CartesianVector deltaPositionOL(pRhs->GetCentroid(pRhs->GetOuterPseudoLayer()) - pLhs->GetCentroid(pLhs->GetOuterPseudoLayer()));
686 if (std::fabs(deltaPositionOL.GetZ()) > std::numeric_limits<float>::epsilon())
687 return (deltaPositionOL.GetZ() > std::numeric_limits<float>::epsilon());
689 if (std::fabs(deltaPositionOL.GetX()) > std::numeric_limits<float>::epsilon())
690 return (deltaPositionOL.GetX() > std::numeric_limits<float>::epsilon());
692 if (std::fabs(deltaPositionOL.GetY()) > std::numeric_limits<float>::epsilon())
693 return (deltaPositionOL.GetY() > std::numeric_limits<float>::epsilon());
696 return SortByPulseHeight(pLhs, pRhs);
701 bool LArClusterHelper::SortByPulseHeight(
const Cluster *
const pLhs,
const Cluster *
const pRhs)
703 return (pLhs->GetHadronicEnergy() > pRhs->GetHadronicEnergy());
708 bool LArClusterHelper::SortHitsByPosition(
const CaloHit *
const pLhs,
const CaloHit *
const pRhs)
710 const CartesianVector deltaPosition(pRhs->GetPositionVector() - pLhs->GetPositionVector());
712 if (std::fabs(deltaPosition.GetZ()) > std::numeric_limits<float>::epsilon())
713 return (deltaPosition.GetZ() > std::numeric_limits<float>::epsilon());
715 if (std::fabs(deltaPosition.GetX()) > std::numeric_limits<float>::epsilon())
716 return (deltaPosition.GetX() > std::numeric_limits<float>::epsilon());
718 if (std::fabs(deltaPosition.GetY()) > std::numeric_limits<float>::epsilon())
719 return (deltaPosition.GetY() > std::numeric_limits<float>::epsilon());
722 return SortHitsByPulseHeight(pLhs, pRhs);
727 bool LArClusterHelper::SortHitsByPositionInX(
const pandora::CaloHit *
const pLhs,
const pandora::CaloHit *
const pRhs)
729 const CartesianVector deltaPosition(pRhs->GetPositionVector() - pLhs->GetPositionVector());
731 if (std::fabs(deltaPosition.GetX()) > std::numeric_limits<float>::epsilon())
732 return (deltaPosition.GetX() > std::numeric_limits<float>::epsilon());
734 return SortHitsByPosition(pLhs, pRhs);
739 bool LArClusterHelper::SortHitsByPulseHeight(
const CaloHit *
const pLhs,
const CaloHit *
const pRhs)
742 return (pLhs->GetHadronicEnergy() > pRhs->GetHadronicEnergy());
747 bool LArClusterHelper::SortCoordinatesByPosition(
const CartesianVector &lhs,
const CartesianVector &rhs)
749 const CartesianVector deltaPosition(rhs - lhs);
751 if (std::fabs(deltaPosition.GetZ()) > std::numeric_limits<float>::epsilon())
752 return (deltaPosition.GetZ() > std::numeric_limits<float>::epsilon());
754 if (std::fabs(deltaPosition.GetX()) > std::numeric_limits<float>::epsilon())
755 return (deltaPosition.GetX() > std::numeric_limits<float>::epsilon());
757 return (deltaPosition.GetY() > std::numeric_limits<float>::epsilon());
Header file for the lar calo hit class.
double dEdX(double KE, const simb::MCParticle *part)
Header file for the cluster helper class.
static int max(int a, int b)
std::set< unsigned int > UIntSet
Detector simulation of raw signals on wires.
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
unsigned int GetDaughterVolumeId() const
Get the daughter volume id.