9 #include "Pandora/AlgorithmHeaders.h" 10 #include "Pandora/AlgorithmTool.h" 26 ShowerStartFinderTool::ShowerStartFinderTool() :
27 m_spineSlidingFitWindow(10),
28 m_longitudinalCoordinateBinSize(1.
f),
29 m_nInitialEnergyBins(5),
30 m_minSigmaDeviation(1.
f),
32 m_longitudinalShowerFraction(0.85
f),
33 m_minShowerOpeningAngle(2.
f),
34 m_molliereRadius(4.5
f),
35 m_showerSlidingFitWindow(1000),
36 m_maxLayerSeparation(5)
43 const HitType hitType,
const CaloHitList &showerSpineHitList, CartesianVector &showerStartPosition, CartesianVector &showerStartDirection)
48 CartesianPointVector hitPositions;
49 for (
const CaloHit *
const pCaloHit : showerSpineHitList)
50 hitPositions.push_back(pCaloHit->GetPositionVector());
64 const bool isEndDownstream(peakDirection.GetZ() > 0.f);
67 showerStartPosition, showerStartDirection);
71 return STATUS_CODE_FAILURE;
74 return STATUS_CODE_SUCCESS;
85 for (
const CaloHit *
const pCaloHit : showerSpineHitList)
87 float hitL(0.
f), hitT(0.
f);
88 const CartesianVector hitPosition(pCaloHit->GetPositionVector());
91 layerToHitMap[spineTwoDSlidingFit.
GetLayer(hitL)].push_back(pCaloHit);
98 float runningDistance(0);
101 for (
auto iter = layerToHitMap.begin(); iter != layerToHitMap.end(); ++iter)
103 const int layer(iter->first);
104 const float layerL(layerFitResultMap.at(layer).GetL());
107 const int higherLayer(std::next(iter) == layerToHitMap.end() ? layer : std::next(iter)->first);
108 const int middleLayer(layer);
109 const int lowerLayer(iter == layerToHitMap.begin() ? layer : std::prev(iter)->first);
110 CartesianVector lowerLayerPosition(0.
f, 0.
f, 0.
f), middleLayerPosition(0.
f, 0.
f, 0.
f), higherLayerPosition(0.
f, 0.
f, 0.
f);
112 spineTwoDSlidingFit.
GetGlobalPosition(layerFitResultMap.at(lowerLayer).GetL(), layerFitResultMap.at(lowerLayer).GetFitT(), lowerLayerPosition);
113 spineTwoDSlidingFit.
GetGlobalPosition(layerFitResultMap.at(middleLayer).GetL(), layerFitResultMap.at(middleLayer).GetFitT(), middleLayerPosition);
114 spineTwoDSlidingFit.
GetGlobalPosition(layerFitResultMap.at(higherLayer).GetL(), layerFitResultMap.at(higherLayer).GetFitT(), higherLayerPosition);
116 const float layerLength = std::next(iter) == layerToHitMap.end() ? 0.f
117 : iter == layerToHitMap.begin() ? 0.f
118 : (middleLayerPosition - lowerLayerPosition).GetMagnitude();
120 for (
const CaloHit *
const pCaloHit : iter->second)
122 const CartesianVector &hitPosition(pCaloHit->GetPositionVector());
124 float hitL(0.
f), hitT(0.
f);
129 CartesianVector localLowerLayerPosition(0.
f, 0.
f, 0.
f), localHigherLayerPosition(0.
f, 0.
f, 0.
f);
133 localLowerLayerPosition = lowerLayerPosition;
134 localHigherLayerPosition = iter == layerToHitMap.begin() ? higherLayerPosition : middleLayerPosition;
138 localLowerLayerPosition = std::next(iter) == layerToHitMap.end() ? lowerLayerPosition : middleLayerPosition;
139 localHigherLayerPosition = higherLayerPosition;
144 const CartesianVector displacement((higherLayerPosition - lowerLayerPosition).GetUnitVector());
145 float longitudinalDisplacement = (displacement.GetDotProduct(hitPosition - lowerLayerPosition) + runningDistance);
148 longitudinalDisplacement += (hitL > layerL ? layerLength : 0.f);
150 longitudinalPositionMap[pCaloHit] = longitudinalDisplacement;
153 runningDistance += layerLength;
164 for (
const CaloHit *pCaloHit : showerSpineHitList)
165 e0 += pCaloHit->GetElectromagneticEnergy();
167 for (
const CaloHit *pCaloHit : showerSpineHitList)
169 const float fractionalEnergy(pCaloHit->GetElectromagneticEnergy() / e0);
170 const float projection(longitudinalPositionMap.at(pCaloHit));
173 if (energySpectrumMap.find(longitudinalIndex) == energySpectrumMap.end())
174 energySpectrumMap[longitudinalIndex] = fractionalEnergy;
176 energySpectrumMap[longitudinalIndex] += fractionalEnergy;
184 const bool isEndDownstream, CartesianVector &showerStartPosition, CartesianVector &showerStartDirection)
const 187 int longitudinalStartBin(0);
192 showerSpineHitList, isEndDownstream, energySpectrumMap.begin(), std::prev(energySpectrumMap.end()));
197 showerSpineHitList, isEndDownstream, energySpectrumMap.rbegin(), std::prev(energySpectrumMap.rend()));
204 showerStartDirection = isEndDownstream ? showerStartDirection : showerStartDirection * (-1.f);
209 template <
typename T>
212 const bool isEndDownstream,
const T startIter,
const T endIter)
const 215 float meanEnergy(0.
f), energySigma(0.
f);
225 for (; iter != endIter; iter++)
228 const float energyDeviation((iter->second - meanEnergy) / energySigma);
234 this->
IsShowerTopology(pShowerPfo, hitType, spineTwoDSlidingFit, longitudinalCoordinate, showerSpineHitList, isEndDownstream))
251 const EnergySpectrumMap &energySpectrumMap,
const bool isEndDownstream,
float &meanEnergy,
float &energySigma)
const 253 auto energySpectrumIter(isEndDownstream ? energySpectrumMap.begin() : std::prev(energySpectrumMap.end()));
257 meanEnergy += energySpectrumIter->second;
258 isEndDownstream ? ++energySpectrumIter : --energySpectrumIter;
263 energySpectrumIter = isEndDownstream ? energySpectrumMap.begin() : std::prev(energySpectrumMap.end());
267 energySigma += std::pow(energySpectrumIter->second - meanEnergy, 2);
268 isEndDownstream ? ++energySpectrumIter : --energySpectrumIter;
271 energySigma = std::sqrt(energySigma / m_nInitialEnergyBins);
277 const float longitudinalDistance,
const CaloHitList &showerSpineHitList,
const bool isEndDownstream)
const 279 CartesianVector showerStartPosition(0.
f, 0.
f, 0.
f), showerStartDirection(0.
f, 0.
f, 0.
f);
283 CartesianPointVector showerRegionPositionVector;
284 if (this->
BuildShowerRegion(pShowerPfo, hitType, showerSpineHitList, showerStartPosition, showerStartDirection, isEndDownstream,
285 showerRegionPositionVector) != STATUS_CODE_SUCCESS)
291 bool isBetween(
false);
292 CartesianVector positiveEdgeStart(0.
f, 0.
f, 0.
f), positiveEdgeEnd(0.
f, 0.
f, 0.
f), positiveEdgeDirection(0.
f, 0.
f, 0.
f);
293 CartesianVector negativeEdgeStart(0.
f, 0.
f, 0.
f), negativeEdgeEnd(0.
f, 0.
f, 0.
f), negativeEdgeDirection(0.
f, 0.
f, 0.
f);
295 if (this->
CharacteriseShowerTopology(showerRegionPositionVector, showerStartPosition, hitType, isEndDownstream, showerStartDirection,
296 positiveEdgeStart, positiveEdgeEnd, negativeEdgeStart, negativeEdgeEnd, isBetween) != STATUS_CODE_SUCCESS)
304 positiveEdgeStart = showerStartPosition;
305 negativeEdgeStart = showerStartPosition;
306 positiveEdgeDirection = positiveEdgeEnd - positiveEdgeStart;
307 negativeEdgeDirection = negativeEdgeEnd - negativeEdgeStart;
309 const float showerOpeningAngle(positiveEdgeDirection.GetOpeningAngle(negativeEdgeDirection) * 180.f / 3.14);
320 const float longitudinalDistance, CartesianVector &globalPosition, CartesianVector &globalDirection)
const 324 float runningDistance(0.
f);
325 int showerStartLayer(0);
326 CartesianVector previousLayerPosition(0.
f, 0.
f, 0.
f);
327 spineTwoDSlidingFit.
GetGlobalPosition(layerFitResultMap.begin()->second.GetL(), layerFitResultMap.begin()->second.GetFitT(), previousLayerPosition);
329 for (
auto iter = std::next(layerFitResultMap.begin()); iter != layerFitResultMap.end(); ++iter)
331 const int layer(iter->first);
332 showerStartLayer = layer;
334 CartesianVector layerPosition(0.
f, 0.
f, 0.
f);
335 spineTwoDSlidingFit.
GetGlobalPosition(layerFitResultMap.at(layer).GetL(), layerFitResultMap.at(layer).GetFitT(), layerPosition);
337 runningDistance += (layerPosition - previousLayerPosition).GetMagnitude();
339 if (runningDistance > longitudinalDistance)
342 previousLayerPosition = layerPosition;
345 const float lCoordinate(layerFitResultMap.at(showerStartLayer).GetL()), tCoordinate(layerFitResultMap.at(showerStartLayer).GetFitT());
346 const float localGradient(layerFitResultMap.at(showerStartLayer).GetGradient());
355 const CaloHitList &showerSpineHitList,
const CartesianVector &showerStartPosition,
const CartesianVector &showerStartDirection,
356 const bool isEndDownstream, CartesianPointVector &showerRegionPositionVector)
const 358 CaloHitList viewShowerHitList;
362 CaloHitList showerRegionHitList;
364 for (
const CaloHit *
const pCaloHit : viewShowerHitList)
366 if (std::find(showerSpineHitList.begin(), showerSpineHitList.end(), pCaloHit) != showerSpineHitList.end())
369 const CartesianVector &hitPosition(pCaloHit->GetPositionVector());
370 float l(showerStartDirection.GetDotProduct(hitPosition - showerStartPosition));
372 l *= isEndDownstream ? 1.f : -1.f;
377 if (showerStartDirection.GetCrossProduct(hitPosition - showerStartPosition).GetMagnitude() >
m_molliereRadius)
380 showerRegionPositionVector.push_back(pCaloHit->GetPositionVector());
381 showerRegionHitList.push_back(pCaloHit);
385 CartesianPointVector coordinateListP, coordinateListN;
395 float showerStartL(0.
f), showerStartT(0.
f);
403 const int layer(iterS->first);
405 if (isEndDownstream && (layer < startLayer))
408 if (!isEndDownstream && (layer > startLayer))
414 if (layerFitResultMapP.end() != iterP)
416 CartesianVector positiveEdgePosition(0.
f, 0.
f, 0.
f);
418 coordinateListP.push_back(positiveEdgePosition);
421 if (layerFitResultMapN.end() != iterN)
423 CartesianVector negativeEdgePosition(0.
f, 0.
f, 0.
f);
425 coordinateListN.push_back(negativeEdgePosition);
429 if ((coordinateListP.size() == 0) || (coordinateListN.size() == 0))
430 return STATUS_CODE_FAILURE;
435 float pMaximumL(std::numeric_limits<float>::max());
436 CartesianVector previousCoordinateP(coordinateListP.front());
438 for (
auto iterP = std::next(coordinateListP.begin()); iterP != coordinateListP.end(); ++iterP)
440 const CartesianVector &coordinateP(*iterP);
441 const float separationSquared((coordinateP - previousCoordinateP).GetMagnitudeSquared());
449 previousCoordinateP = coordinateP;
452 float nMaximumL(std::numeric_limits<float>::max());
453 CartesianVector previousCoordinateN(coordinateListN.front());
455 for (
auto iterN = std::next(coordinateListN.begin()); iterN != coordinateListN.end(); ++iterN)
457 const CartesianVector &coordinateN(*iterN);
458 const float separationSquared((coordinateN - previousCoordinateN).GetMagnitudeSquared());
466 previousCoordinateN = coordinateN;
470 showerRegionPositionVector.clear();
472 for (
const CaloHit *
const pCaloHit : showerRegionHitList)
474 float thisL(0.
f), thisT(0.
f);
475 const CartesianVector &hitPosition(pCaloHit->GetPositionVector());
486 showerRegionPositionVector.push_back(pCaloHit->GetPositionVector());
489 catch (
const StatusCodeException &)
491 return STATUS_CODE_FAILURE;
494 return STATUS_CODE_SUCCESS;
500 const HitType hitType,
const bool isEndDownstream,
const CartesianVector &showerStartDirection, CartesianVector &positiveEdgeStart,
501 CartesianVector &positiveEdgeEnd, CartesianVector &negativeEdgeStart, CartesianVector &negativeEdgeEnd,
bool &isBetween)
const 512 float showerStartL(0.
f), showerStartT(0.
f);
520 bool isFirstBetween(
false), isLastBetween(
false);
521 CartesianPointVector coordinateListP, coordinateListN;
525 int layer(iterS->first);
527 if (isEndDownstream && (layer < startLayer))
530 if (!isEndDownstream && (layer > startLayer))
536 CartesianVector positiveEdgePosition(0.
f, 0.
f, 0.
f), negativeEdgePosition(0.
f, 0.
f, 0.
f);
537 if (layerFitResultMapP.end() != iterP)
540 coordinateListP.push_back(positiveEdgePosition);
543 if (layerFitResultMapN.end() != iterN)
546 coordinateListN.push_back(negativeEdgePosition);
549 if ((layerFitResultMapP.end() != iterP) && (layerFitResultMapN.end() != iterN))
551 const CartesianVector positiveDisplacement((positiveEdgePosition - showerStartPosition).GetUnitVector());
552 const bool isPositiveClockwise(this->
IsClockwiseRotation(showerStartDirection, positiveDisplacement));
554 const CartesianVector negativeDisplacement((negativeEdgePosition - showerStartPosition).GetUnitVector());
555 const bool isNegativeClockwise(this->
IsClockwiseRotation(showerStartDirection, negativeDisplacement));
560 isFirstBetween = (isPositiveClockwise != isNegativeClockwise);
562 isLastBetween = (isPositiveClockwise != isNegativeClockwise);
566 isBetween = (isFirstBetween || isLastBetween);
570 positiveEdgeStart, positiveEdgeEnd) != STATUS_CODE_SUCCESS)
572 return STATUS_CODE_FAILURE;
576 negativeEdgeStart, negativeEdgeEnd) != STATUS_CODE_SUCCESS)
578 return STATUS_CODE_FAILURE;
581 catch (
const StatusCodeException &)
583 return STATUS_CODE_FAILURE;
586 return STATUS_CODE_SUCCESS;
594 const float openingAngleFromCore(showerStartDirection.GetOpeningAngle(displacementVector));
596 const CartesianVector clockwiseRotation(
597 displacementVector.GetZ() * std::sin(openingAngleFromCore) + displacementVector.GetX() * std::cos(openingAngleFromCore), 0.f,
598 displacementVector.GetZ() * std::cos(openingAngleFromCore) - displacementVector.GetX() * std::sin(openingAngleFromCore));
600 const CartesianVector anticlockwiseRotation(
601 displacementVector.GetZ() * std::sin(-1.
f * openingAngleFromCore) + displacementVector.GetX() * std::cos(-1.
f * openingAngleFromCore), 0.f,
602 displacementVector.GetZ() * std::cos(-1.
f * openingAngleFromCore) - displacementVector.GetX() * std::sin(-1.
f * openingAngleFromCore));
604 const float clockwiseT((clockwiseRotation - showerStartDirection).GetMagnitude());
605 const float anticlockwiseT((anticlockwiseRotation - showerStartDirection).GetMagnitude());
606 const bool isClockwise(clockwiseT < anticlockwiseT);
614 const LayerFitResultMap &layerFitResultMap,
const CartesianVector &showerStartPosition,
const int showerStartLayer,
615 const int showerEndLayer, CartesianVector &boundaryEdgeStart, CartesianVector &boundaryEdgeEnd)
const 617 int boundaryStartLayer(std::numeric_limits<int>::max());
618 int boundaryEndLayer(std::numeric_limits<int>::max());
620 for (
auto &entry : layerFitResultMap)
622 const int bestStartSeparation(
std::abs(showerStartLayer - boundaryStartLayer));
623 const int thisStartSeparation(
std::abs(showerStartLayer - entry.first));
625 if (((bestStartSeparation - thisStartSeparation) > 0) && (thisStartSeparation < bestStartSeparation))
626 boundaryStartLayer = entry.first;
628 const int bestEndSeparation(
std::abs(showerEndLayer - boundaryEndLayer));
629 const int thisEndSeparation(
std::abs(showerEndLayer - entry.first));
631 if (((bestEndSeparation - thisEndSeparation) > 0) && (thisEndSeparation < bestEndSeparation))
632 boundaryEndLayer = entry.first;
636 return STATUS_CODE_FAILURE;
638 const float showerStartBoundaryLocalL(layerFitResultMap.at(boundaryStartLayer).GetL()),
639 showerStartBoundaryLocalT(layerFitResultMap.at(boundaryStartLayer).GetFitT());
640 const float showerEndBoundaryLocalL(layerFitResultMap.at(boundaryEndLayer).GetL()),
641 showerEndBoundaryLocalT(layerFitResultMap.at(boundaryEndLayer).GetFitT());
647 if ((showerStartPosition - boundaryEdgeEnd).GetMagnitudeSquared() < (showerStartPosition - boundaryEdgeStart).GetMagnitude())
649 const CartesianVector startTemp(boundaryEdgeStart), endTemp(boundaryEdgeEnd);
651 boundaryEdgeStart = endTemp;
652 boundaryEdgeEnd = startTemp;
655 return STATUS_CODE_SUCCESS;
662 PANDORA_RETURN_RESULT_IF_AND_IF(
663 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SpineSlidingFitWindow",
m_spineSlidingFitWindow));
665 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
668 PANDORA_RETURN_RESULT_IF_AND_IF(
669 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"nInitialEnergyBins",
m_nInitialEnergyBins));
671 PANDORA_RETURN_RESULT_IF_AND_IF(
672 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinSigmaDeviation",
m_minSigmaDeviation));
674 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxEdgeGap",
m_maxEdgeGap));
676 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
679 PANDORA_RETURN_RESULT_IF_AND_IF(
680 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinShowerOpeningAngle",
m_minShowerOpeningAngle));
682 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MolliereRadius",
m_molliereRadius));
684 PANDORA_RETURN_RESULT_IF_AND_IF(
685 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ShowerSlidingFitWindow",
m_showerSlidingFitWindow));
687 PANDORA_RETURN_RESULT_IF_AND_IF(
688 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxLayerSeparation",
m_maxLayerSeparation));
690 return STATUS_CODE_SUCCESS;
std::map< int, pandora::CaloHitList > LayerToHitMap
float m_longitudinalShowerFraction
The shower region fraction considered.
Header file for the lar two dimensional sliding shower fit result class.
void CharacteriseInitialEnergy(const EnergySpectrumMap &energySpectrumMap, const bool isEndDownstream, float &meanEnergy, float &energySigma) const
Find the mean and standard deviation of the energy depositions in the initial region.
Header file for the pfo helper class.
Header file for the connection pathway helper class.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
float m_minShowerOpeningAngle
The min. opening angle of a sensible shower.
void ObtainLongitudinalDecomposition(const TwoDSlidingFitResult &spineTwoDSlidingFit, const pandora::CaloHitList &showerSpineHitList, LongitudinalPositionMap &longitudinalPositionMap) const
Create the [shower spine hit -> shower spine fit longitudinal projection] map.
float m_longitudinalCoordinateBinSize
The longitudinal coordinate bin size.
int m_maxLayerSeparation
The max. allowed separation between the shower start and boundary start layers.
const TwoDSlidingFitResult & GetShowerFitResult() const
Get the sliding fit result for the full shower cluster.
constexpr auto abs(T v)
Returns the absolute value of the argument.
unsigned int m_showerSlidingFitWindow
The sliding window used to fit the shower region.
pandora::StatusCode BuildShowerRegion(const pandora::ParticleFlowObject *const pShowerPfo, const pandora::HitType hitType, const pandora::CaloHitList &showerSpineHitList, const pandora::CartesianVector &showerStartPosition, const pandora::CartesianVector &showerStartDirection, const bool isEndDownstream, pandora::CartesianPointVector &showerRegionPositionVector) const
Build the downstream 'shower region' at a given longitudinal distance along the spine.
unsigned int m_nInitialEnergyBins
The number of longitudinal bins that define the initial region.
TwoDSlidingShowerFitResult class.
Header file for the geometry helper class.
std::map< const pandora::CaloHit *, float > LongitudinalPositionMap
void GetEnergyDistribution(const pandora::CaloHitList &showerSpineHitList, const LongitudinalPositionMap &longitudinalPositionMap, EnergySpectrumMap &energySpectrumMap) const
Create the longituidnal energy distribution.
int GetMaxLayer() const
Get the maximum occupied layer in the sliding fit.
float m_maxEdgeGap
The max. allowed layer gap in a shower boundary.
Header file for the lar two dimensional sliding fit result class.
float m_molliereRadius
The max. distance from the shower core of a collected shower region hit.
std::map< int, LayerFitResult > LayerFitResultMap
pandora::StatusCode GetBoundaryExtremalPoints(const TwoDSlidingShowerFitResult &showerTwoDSlidingFit, const LayerFitResultMap &layerFitResultMap, const pandora::CartesianVector &showerStartPosition, const int showerStartLayer, const int showerEndLayer, pandora::CartesianVector &boundaryEdgeStart, pandora::CartesianVector &boundaryEdgeEnd) const
Determine the start and end positions of a shower boundary.
static float GetWirePitch(const pandora::Pandora &pandora, const pandora::HitType view, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
const TwoDSlidingFitResult & GetPositiveEdgeFitResult() const
Get the sliding fit result for the positive shower edge.
void GetGlobalDirection(const float dTdL, pandora::CartesianVector &direction) const
Get global direction coordinates for given sliding linear fit gradient.
const LayerFitResultMap & GetLayerFitResultMap() const
Get the layer fit result map.
bool IsShowerTopology(const pandora::ParticleFlowObject *const pShowerPfo, const pandora::HitType hitType, const TwoDSlidingFitResult &spineTwoDSlidingFit, const float longitudinalDistance, const pandora::CaloHitList &showerSpineHitList, const bool isEndDownstream) const
Whether a sensible shower cascade looks to originate at a given position.
pandora::StatusCode CharacteriseShowerTopology(const pandora::CartesianPointVector &showerRegionPositionVector, const pandora::CartesianVector &showerStartPosition, const pandora::HitType hitType, const bool isEndDownstream, const pandora::CartesianVector &showerStartDirection, pandora::CartesianVector &positiveEdgeStart, pandora::CartesianVector &positiveEdgeEnd, pandora::CartesianVector &negativeEdgeStart, pandora::CartesianVector &negativeEdgeEnd, bool &isBetween) const
Parameterise the topological structure of the shower region.
SortByDistanceToPoint class.
bool IsClockwiseRotation(const pandora::CartesianVector &showerStartDirection, const pandora::CartesianVector &displacementVector) const
Determine whether a point lies on the RHS or LHS (wrt +ve Z) of the shower core.
const TwoDSlidingFitResult & GetNegativeEdgeFitResult() const
Get the sliding fit result for the negative shower edge.
void GetGlobalPosition(const float rL, const float rT, pandora::CartesianVector &position) const
Get global coordinates for given sliding linear fit coordinates.
float m_minSigmaDeviation
The min. average energy deviation of a candidate shower start.
void ConvertLongitudinalProjectionToGlobal(const TwoDSlidingFitResult &spineTwoDSlidingFit, const float longitudinalDistance, pandora::CartesianVector &globalPosition, pandora::CartesianVector &globalDirection) const
Determine the (X,Y,Z) position and direction at a given longitudinal distance along the spine...
pandora::StatusCode Run(const pandora::ParticleFlowObject *const pShowerPfo, const pandora::CartesianVector &peakDirection, const pandora::HitType hitType, const pandora::CaloHitList &showerSpineHitList, pandora::CartesianVector &showerStartPosition, pandora::CartesianVector &showerStartDirection)
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.
std::map< int, float > EnergySpectrumMap
void GetLocalPosition(const pandora::CartesianVector &position, float &rL, float &rT) const
Get local sliding fit coordinates for a given global position.
TwoDSlidingFitResult class.
int GetLayer(const float rL) const
Get layer number for given sliding linear fit longitudinal coordinate.
unsigned int m_spineSlidingFitWindow
The sliding window used to fit the shower spine.
int FindShowerStartLongitudinalCoordinate(const pandora::ParticleFlowObject *const pShowerPfo, const pandora::HitType hitType, const TwoDSlidingFitResult &spineTwoDSlidingFit, const EnergySpectrumMap &energySpectrumMap, const pandora::CaloHitList &showerSpineHitList, const bool isEndDownstream, const T startIter, const T endIter) const
Find the longitudinal bin which corresponds to the start position of the shower cascade.
void FindShowerStartAndDirection(const pandora::ParticleFlowObject *const pShowerPfo, const pandora::HitType hitType, const TwoDSlidingFitResult &spineTwoDSlidingFit, const EnergySpectrumMap &energySpectrumMap, const pandora::CaloHitList &showerSpineHitList, const bool isEndDownstream, pandora::CartesianVector &showerStartPosition, pandora::CartesianVector &showerStartDirection) const
Find the position at which the shower cascade looks to originate, and its initial direction...