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);
232 this->
IsShowerTopology(pShowerPfo, hitType, spineTwoDSlidingFit, longitudinalCoordinate, showerSpineHitList, isEndDownstream))
244 const EnergySpectrumMap &energySpectrumMap,
const bool isEndDownstream,
float &meanEnergy,
float &energySigma)
const 246 auto energySpectrumIter(isEndDownstream ? energySpectrumMap.begin() : std::prev(energySpectrumMap.end()));
250 meanEnergy += energySpectrumIter->second;
251 isEndDownstream ? ++energySpectrumIter : --energySpectrumIter;
256 energySpectrumIter = isEndDownstream ? energySpectrumMap.begin() : std::prev(energySpectrumMap.end());
260 energySigma += std::pow(energySpectrumIter->second - meanEnergy, 2);
261 isEndDownstream ? ++energySpectrumIter : --energySpectrumIter;
264 energySigma = std::sqrt(energySigma / m_nInitialEnergyBins);
270 const float longitudinalDistance,
const CaloHitList &showerSpineHitList,
const bool isEndDownstream)
const 272 CartesianVector showerStartPosition(0.
f, 0.
f, 0.
f), showerStartDirection(0.
f, 0.
f, 0.
f);
276 CartesianPointVector showerRegionPositionVector;
277 if (this->
BuildShowerRegion(pShowerPfo, hitType, showerSpineHitList, showerStartPosition, showerStartDirection, isEndDownstream,
278 showerRegionPositionVector) != STATUS_CODE_SUCCESS)
284 bool isBetween(
false);
285 CartesianVector positiveEdgeStart(0.
f, 0.
f, 0.
f), positiveEdgeEnd(0.
f, 0.
f, 0.
f), positiveEdgeDirection(0.
f, 0.
f, 0.
f);
286 CartesianVector negativeEdgeStart(0.
f, 0.
f, 0.
f), negativeEdgeEnd(0.
f, 0.
f, 0.
f), negativeEdgeDirection(0.
f, 0.
f, 0.
f);
288 if (this->
CharacteriseShowerTopology(showerRegionPositionVector, showerStartPosition, hitType, isEndDownstream, showerStartDirection,
289 positiveEdgeStart, positiveEdgeEnd, negativeEdgeStart, negativeEdgeEnd, isBetween) != STATUS_CODE_SUCCESS)
297 positiveEdgeStart = showerStartPosition;
298 negativeEdgeStart = showerStartPosition;
299 positiveEdgeDirection = positiveEdgeEnd - positiveEdgeStart;
300 negativeEdgeDirection = negativeEdgeEnd - negativeEdgeStart;
302 const float showerOpeningAngle(positiveEdgeDirection.GetOpeningAngle(negativeEdgeDirection) * 180.f / 3.14);
313 const float longitudinalDistance, CartesianVector &globalPosition, CartesianVector &globalDirection)
const 317 float runningDistance(0.
f);
318 int showerStartLayer(0);
319 CartesianVector previousLayerPosition(0.
f, 0.
f, 0.
f);
320 spineTwoDSlidingFit.
GetGlobalPosition(layerFitResultMap.begin()->second.GetL(), layerFitResultMap.begin()->second.GetFitT(), previousLayerPosition);
322 for (
auto iter = std::next(layerFitResultMap.begin()); iter != layerFitResultMap.end(); ++iter)
324 const int layer(iter->first);
325 showerStartLayer = layer;
327 CartesianVector layerPosition(0.
f, 0.
f, 0.
f);
328 spineTwoDSlidingFit.
GetGlobalPosition(layerFitResultMap.at(layer).GetL(), layerFitResultMap.at(layer).GetFitT(), layerPosition);
330 runningDistance += (layerPosition - previousLayerPosition).GetMagnitude();
332 if (runningDistance > longitudinalDistance)
335 previousLayerPosition = layerPosition;
338 const float lCoordinate(layerFitResultMap.at(showerStartLayer).GetL()), tCoordinate(layerFitResultMap.at(showerStartLayer).GetFitT());
339 const float localGradient(layerFitResultMap.at(showerStartLayer).GetGradient());
348 const CaloHitList &showerSpineHitList,
const CartesianVector &showerStartPosition,
const CartesianVector &showerStartDirection,
349 const bool isEndDownstream, CartesianPointVector &showerRegionPositionVector)
const 351 CaloHitList viewShowerHitList;
355 CaloHitList showerRegionHitList;
357 for (
const CaloHit *
const pCaloHit : viewShowerHitList)
359 if (std::find(showerSpineHitList.begin(), showerSpineHitList.end(), pCaloHit) != showerSpineHitList.end())
362 const CartesianVector &hitPosition(pCaloHit->GetPositionVector());
363 float l(showerStartDirection.GetDotProduct(hitPosition - showerStartPosition));
365 l *= isEndDownstream ? 1.f : -1.f;
370 if (showerStartDirection.GetCrossProduct(hitPosition - showerStartPosition).GetMagnitude() >
m_molliereRadius)
373 showerRegionPositionVector.push_back(pCaloHit->GetPositionVector());
374 showerRegionHitList.push_back(pCaloHit);
378 CartesianPointVector coordinateListP, coordinateListN;
388 float showerStartL(0.
f), showerStartT(0.
f);
396 const int layer(iterS->first);
398 if (isEndDownstream && (layer < startLayer))
401 if (!isEndDownstream && (layer > startLayer))
407 if (layerFitResultMapP.end() != iterP)
409 CartesianVector positiveEdgePosition(0.
f, 0.
f, 0.
f);
411 coordinateListP.push_back(positiveEdgePosition);
414 if (layerFitResultMapN.end() != iterN)
416 CartesianVector negativeEdgePosition(0.
f, 0.
f, 0.
f);
418 coordinateListN.push_back(negativeEdgePosition);
422 if ((coordinateListP.size() == 0) || (coordinateListN.size() == 0))
423 return STATUS_CODE_FAILURE;
428 float pMaximumL(std::numeric_limits<float>::max());
429 CartesianVector previousCoordinateP(coordinateListP.front());
431 for (
auto iterP = std::next(coordinateListP.begin()); iterP != coordinateListP.end(); ++iterP)
433 const CartesianVector &coordinateP(*iterP);
434 const float separationSquared((coordinateP - previousCoordinateP).GetMagnitudeSquared());
442 previousCoordinateP = coordinateP;
445 float nMaximumL(std::numeric_limits<float>::max());
446 CartesianVector previousCoordinateN(coordinateListN.front());
448 for (
auto iterN = std::next(coordinateListN.begin()); iterN != coordinateListN.end(); ++iterN)
450 const CartesianVector &coordinateN(*iterN);
451 const float separationSquared((coordinateN - previousCoordinateN).GetMagnitudeSquared());
459 previousCoordinateN = coordinateN;
463 showerRegionPositionVector.clear();
465 for (
const CaloHit *
const pCaloHit : showerRegionHitList)
467 float thisL(0.
f), thisT(0.
f);
468 const CartesianVector &hitPosition(pCaloHit->GetPositionVector());
479 showerRegionPositionVector.push_back(pCaloHit->GetPositionVector());
482 catch (
const StatusCodeException &)
484 return STATUS_CODE_FAILURE;
487 return STATUS_CODE_SUCCESS;
493 const HitType hitType,
const bool isEndDownstream,
const CartesianVector &showerStartDirection, CartesianVector &positiveEdgeStart,
494 CartesianVector &positiveEdgeEnd, CartesianVector &negativeEdgeStart, CartesianVector &negativeEdgeEnd,
bool &isBetween)
const 505 float showerStartL(0.
f), showerStartT(0.
f);
513 bool isFirstBetween(
false), isLastBetween(
false);
514 CartesianPointVector coordinateListP, coordinateListN;
518 int layer(iterS->first);
520 if (isEndDownstream && (layer < startLayer))
523 if (!isEndDownstream && (layer > startLayer))
529 CartesianVector positiveEdgePosition(0.
f, 0.
f, 0.
f), negativeEdgePosition(0.
f, 0.
f, 0.
f);
530 if (layerFitResultMapP.end() != iterP)
533 coordinateListP.push_back(positiveEdgePosition);
536 if (layerFitResultMapN.end() != iterN)
539 coordinateListN.push_back(negativeEdgePosition);
542 if ((layerFitResultMapP.end() != iterP) && (layerFitResultMapN.end() != iterN))
544 const CartesianVector positiveDisplacement((positiveEdgePosition - showerStartPosition).GetUnitVector());
545 const bool isPositiveClockwise(this->
IsClockwiseRotation(showerStartDirection, positiveDisplacement));
547 const CartesianVector negativeDisplacement((negativeEdgePosition - showerStartPosition).GetUnitVector());
548 const bool isNegativeClockwise(this->
IsClockwiseRotation(showerStartDirection, negativeDisplacement));
553 isFirstBetween = (isPositiveClockwise != isNegativeClockwise);
555 isLastBetween = (isPositiveClockwise != isNegativeClockwise);
559 isBetween = (isFirstBetween || isLastBetween);
563 positiveEdgeStart, positiveEdgeEnd) != STATUS_CODE_SUCCESS)
565 return STATUS_CODE_FAILURE;
569 negativeEdgeStart, negativeEdgeEnd) != STATUS_CODE_SUCCESS)
571 return STATUS_CODE_FAILURE;
574 catch (
const StatusCodeException &)
576 return STATUS_CODE_FAILURE;
579 return STATUS_CODE_SUCCESS;
587 const float openingAngleFromCore(showerStartDirection.GetOpeningAngle(displacementVector));
589 const CartesianVector clockwiseRotation(
590 displacementVector.GetZ() * std::sin(openingAngleFromCore) + displacementVector.GetX() * std::cos(openingAngleFromCore), 0.f,
591 displacementVector.GetZ() * std::cos(openingAngleFromCore) - displacementVector.GetX() * std::sin(openingAngleFromCore));
593 const CartesianVector anticlockwiseRotation(
594 displacementVector.GetZ() * std::sin(-1.
f * openingAngleFromCore) + displacementVector.GetX() * std::cos(-1.
f * openingAngleFromCore), 0.f,
595 displacementVector.GetZ() * std::cos(-1.
f * openingAngleFromCore) - displacementVector.GetX() * std::sin(-1.
f * openingAngleFromCore));
597 const float clockwiseT((clockwiseRotation - showerStartDirection).GetMagnitude());
598 const float anticlockwiseT((anticlockwiseRotation - showerStartDirection).GetMagnitude());
599 const bool isClockwise(clockwiseT < anticlockwiseT);
607 const LayerFitResultMap &layerFitResultMap,
const CartesianVector &showerStartPosition,
const int showerStartLayer,
608 const int showerEndLayer, CartesianVector &boundaryEdgeStart, CartesianVector &boundaryEdgeEnd)
const 610 int boundaryStartLayer(std::numeric_limits<int>::max());
611 int boundaryEndLayer(std::numeric_limits<int>::max());
613 for (
auto &entry : layerFitResultMap)
615 const int bestStartSeparation(
std::abs(showerStartLayer - boundaryStartLayer));
616 const int thisStartSeparation(
std::abs(showerStartLayer - entry.first));
618 if (((bestStartSeparation - thisStartSeparation) > 0) && (thisStartSeparation < bestStartSeparation))
619 boundaryStartLayer = entry.first;
621 const int bestEndSeparation(
std::abs(showerEndLayer - boundaryEndLayer));
622 const int thisEndSeparation(
std::abs(showerEndLayer - entry.first));
624 if (((bestEndSeparation - thisEndSeparation) > 0) && (thisEndSeparation < bestEndSeparation))
625 boundaryEndLayer = entry.first;
629 return STATUS_CODE_FAILURE;
631 const float showerStartBoundaryLocalL(layerFitResultMap.at(boundaryStartLayer).GetL()),
632 showerStartBoundaryLocalT(layerFitResultMap.at(boundaryStartLayer).GetFitT());
633 const float showerEndBoundaryLocalL(layerFitResultMap.at(boundaryEndLayer).GetL()),
634 showerEndBoundaryLocalT(layerFitResultMap.at(boundaryEndLayer).GetFitT());
640 if ((showerStartPosition - boundaryEdgeEnd).GetMagnitudeSquared() < (showerStartPosition - boundaryEdgeStart).GetMagnitude())
642 const CartesianVector startTemp(boundaryEdgeStart), endTemp(boundaryEdgeEnd);
644 boundaryEdgeStart = endTemp;
645 boundaryEdgeEnd = startTemp;
648 return STATUS_CODE_SUCCESS;
655 PANDORA_RETURN_RESULT_IF_AND_IF(
656 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SpineSlidingFitWindow",
m_spineSlidingFitWindow));
658 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
661 PANDORA_RETURN_RESULT_IF_AND_IF(
662 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"nInitialEnergyBins",
m_nInitialEnergyBins));
664 PANDORA_RETURN_RESULT_IF_AND_IF(
665 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinSigmaDeviation",
m_minSigmaDeviation));
667 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxEdgeGap",
m_maxEdgeGap));
669 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
672 PANDORA_RETURN_RESULT_IF_AND_IF(
673 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinShowerOpeningAngle",
m_minShowerOpeningAngle));
675 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MolliereRadius",
m_molliereRadius));
677 PANDORA_RETURN_RESULT_IF_AND_IF(
678 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ShowerSlidingFitWindow",
m_showerSlidingFitWindow));
680 PANDORA_RETURN_RESULT_IF_AND_IF(
681 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxLayerSeparation",
m_maxLayerSeparation));
683 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...