9 #include "Pandora/AlgorithmHeaders.h" 10 #include "Pandora/AlgorithmTool.h" 25 ShowerSpineFinderTool::ShowerSpineFinderTool() :
26 m_hitThresholdForSpine(7),
27 m_growingFitInitialLength(10.
f),
28 m_initialFitDistanceToLine(0.5
f),
29 m_minInitialHitsFound(7),
31 m_localSlidingFitWindow(10),
32 m_growingFitSegmentLength(5.
f),
33 m_highResolutionSlidingFitWindow(5),
34 m_distanceToLine(0.75
f),
35 m_hitConnectionDistance(0.75
f)
42 const CartesianVector &peakDirection, CaloHitList &unavailableHitList, CaloHitList &showerSpineHitList)
46 this->
FindShowerSpine(pViewHitList, nuVertex2D, peakDirection, unavailableHitList, showerSpineHitList);
50 return STATUS_CODE_NOT_FOUND;
52 return STATUS_CODE_SUCCESS;
58 const CartesianVector &initialDirection, CaloHitList &unavailableHitList, CaloHitList &showerSpineHitList)
const 62 CartesianPointVector runningFitPositionVector;
64 for (
const CaloHit *
const pCaloHit : *pViewHitList)
66 const CartesianVector &hitPosition(pCaloHit->GetPositionVector());
67 const CartesianVector &displacementVector(hitPosition - nuVertex2D);
68 const float l(initialDirection.GetDotProduct(displacementVector));
69 const float t(initialDirection.GetCrossProduct(displacementVector).GetMagnitude());
76 if (std::find(unavailableHitList.begin(), unavailableHitList.end(), pCaloHit) == unavailableHitList.end())
78 showerSpineHitList.push_back(pCaloHit);
81 runningFitPositionVector.push_back(hitPosition);
88 showerSpineHitList.clear();
93 unsigned int count(0);
94 bool hitsCollected(
true);
95 const bool isEndDownstream(initialDirection.GetZ() > 0.f);
97 CartesianVector extrapolatedStartPosition(nuVertex2D), extrapolatedDirection(initialDirection);
98 CartesianVector extrapolatedEndPosition(extrapolatedStartPosition + (extrapolatedDirection * highestL));
100 while (hitsCollected)
106 const int excessHitsInFit(runningFitPositionVector.size() -
m_maxFittingHits);
108 if (excessHitsInFit > 0)
111 std::sort(runningFitPositionVector.begin(), runningFitPositionVector.end(),
114 for (
int i = 0; i < excessHitsInFit; ++i)
115 runningFitPositionVector.erase(std::prev(runningFitPositionVector.end()));
120 extrapolatedStartPosition = count == 1 ? extrapolatedEndPosition
123 extrapolatedDirection =
127 hitsCollected = this->
CollectSubsectionHits(extrapolatedFit, extrapolatedStartPosition, extrapolatedEndPosition,
128 extrapolatedDirection, isEndDownstream, pViewHitList, runningFitPositionVector, unavailableHitList, showerSpineHitList);
135 extrapolatedStartPosition = count == 1 ? extrapolatedStartPosition
142 hitsCollected = this->
CollectSubsectionHits(microExtrapolatedFit, extrapolatedStartPosition, extrapolatedEndPosition,
143 extrapolatedDirection, isEndDownstream, pViewHitList, runningFitPositionVector, unavailableHitList, showerSpineHitList);
146 catch (
const StatusCodeException &)
156 const CartesianVector &extrapolatedStartPosition,
const CartesianVector &extrapolatedEndPosition,
157 const CartesianVector &extrapolatedDirection,
const bool isEndDownstream,
const CaloHitList *
const pViewHitList,
158 CartesianPointVector &runningFitPositionVector, CaloHitList &unavailableHitList, CaloHitList &showerSpineHitList)
const 160 float extrapolatedStartL(0.
f), extrapolatedStartT(0.
f);
161 extrapolatedFit.
GetLocalPosition(extrapolatedStartPosition, extrapolatedStartL, extrapolatedStartT);
163 float extrapolatedEndL(0.
f), extrapolatedEndT(0.
f);
164 extrapolatedFit.
GetLocalPosition(extrapolatedEndPosition, extrapolatedEndL, extrapolatedEndT);
166 CaloHitList collectedHits;
168 for (
const CaloHit *
const pCaloHit : *pViewHitList)
170 if (std::find(showerSpineHitList.begin(), showerSpineHitList.end(), pCaloHit) != showerSpineHitList.end())
173 if (std::find(unavailableHitList.begin(), unavailableHitList.end(), pCaloHit) != unavailableHitList.end())
176 const CartesianVector &hitPosition(pCaloHit->GetPositionVector());
178 float hitL(0.
f), hitT(0.
f);
182 if (isEndDownstream && ((hitL < extrapolatedStartL) || (hitL > extrapolatedEndL)))
185 if (!isEndDownstream && ((hitL > extrapolatedStartL) || (hitL < extrapolatedEndL)))
191 collectedHits.push_back(pCaloHit);
195 const CartesianVector closestPointInHit(
199 collectedHits.push_back(pCaloHit);
203 const int nInitialHits(showerSpineHitList.size());
206 this->
CollectConnectedHits(collectedHits, extrapolatedStartPosition, extrapolatedDirection, runningFitPositionVector, showerSpineHitList);
208 const int nFinalHits(showerSpineHitList.size());
210 return (nFinalHits != nInitialHits);
216 const CartesianVector &lineDirection,
const float distanceToLine)
const 218 const float transverseDistanceFromLine(lineDirection.GetCrossProduct(hitPosition - lineStart).GetMagnitude());
220 if (transverseDistanceFromLine > distanceToLine)
229 const CartesianVector &extrapolatedDirection, CartesianPointVector &runningFitPositionVector, CaloHitList &showerSpineHitList)
const 237 for (
const CaloHit *
const pCaloHit : collectedHits)
239 if (std::find(showerSpineHitList.begin(), showerSpineHitList.end(), pCaloHit) != showerSpineHitList.end())
242 CartesianVector hitPosition(pCaloHit->GetPositionVector());
254 runningFitPositionVector.push_back(hitPosition);
255 showerSpineHitList.push_back(pCaloHit);
264 float closestDistanceSqaured(std::numeric_limits<float>::max());
266 for (
const CartesianVector &testPosition : testPositions)
268 const float separationSquared((testPosition - position).GetMagnitudeSquared());
270 if (separationSquared < closestDistanceSqaured)
271 closestDistanceSqaured = separationSquared;
274 return std::sqrt(closestDistanceSqaured);
281 PANDORA_RETURN_RESULT_IF_AND_IF(
282 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"HitThresholdForSpine",
m_hitThresholdForSpine));
284 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
287 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
290 PANDORA_RETURN_RESULT_IF_AND_IF(
291 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinInitialHitsFound",
m_minInitialHitsFound));
293 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxFittingHits",
m_maxFittingHits));
295 PANDORA_RETURN_RESULT_IF_AND_IF(
296 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"LocalSlidingFitWindow",
m_localSlidingFitWindow));
298 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
301 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
304 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"DistanceToLine",
m_distanceToLine));
306 PANDORA_RETURN_RESULT_IF_AND_IF(
307 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"HitConnectionDistance",
m_hitConnectionDistance));
309 return STATUS_CODE_SUCCESS;
pandora::StatusCode Run(const pandora::CartesianVector &nuVertex3D, const pandora::CaloHitList *const pViewHitList, const pandora::HitType hitType, const pandora::CartesianVector &peakDirection, pandora::CaloHitList &unavailableHitList, pandora::CaloHitList &showerSpineHitList)
Header file for the connection pathway helper class.
Header file for the lar hit width helper class.
unsigned int m_minInitialHitsFound
The min. number of hits collected in the first step for continuation.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
float m_initialFitDistanceToLine
The max. proximity to the spine projection for collection in the first step.
static pandora::CartesianVector ProjectPosition(const pandora::Pandora &pandora, const pandora::CartesianVector &position3D, const pandora::HitType view)
Project 3D position into a given 2D view.
float m_hitConnectionDistance
The max. separation between connected hits.
void FindShowerSpine(const pandora::CaloHitList *const pViewHitList, const pandora::CartesianVector &nuVertex2D, const pandora::CartesianVector &initialDirection, pandora::CaloHitList &unavailableHitList, pandora::CaloHitList &showerSpineHitList) const
Perform a running fit to collect the hits of the shower spine.
static pandora::CartesianVector GetClosestPointToLine2D(const pandora::CartesianVector &lineStart, const pandora::CartesianVector &lineDirection, const pandora::CaloHit *const pCaloHit)
Consider the hit width to find the closest position of a calo hit to a specified line.
float GetClosestDistance(const pandora::CartesianVector &position, const pandora::CartesianPointVector &testPositions) const
Find the smallest distance between a position and a list of other positions.
pandora::CartesianVector GetGlobalMinLayerDirection() const
Get global direction corresponding to the fit result in minimum fit layer.
bool CollectSubsectionHits(const TwoDSlidingFitResult &extrapolatedFit, const pandora::CartesianVector &extrapolatedStartPosition, const pandora::CartesianVector &extrapolatedEndPosition, const pandora::CartesianVector &extrapolatedDirection, const bool isEndDownstream, const pandora::CaloHitList *const pViewHitList, pandora::CartesianPointVector &runningFitPositionVector, pandora::CaloHitList &unavailableHitList, pandora::CaloHitList &showerSpineHitList) const
Perform a running fit step: collect hits which lie close to the shower spine projection.
float m_distanceToLine
The max. proximity to the spine projection for collection.
unsigned int m_highResolutionSlidingFitWindow
The high resolution sliding fit window for spine fits.
Header file for the geometry helper class.
bool IsCloseToLine(const pandora::CartesianVector &hitPosition, const pandora::CartesianVector &lineStart, const pandora::CartesianVector &lineDirection, const float distanceToLine) const
Determine whether a hit lies close to the shower spine projection.
unsigned int m_maxFittingHits
The number of hits to consider in the running fit.
Header file for the lar two dimensional sliding fit result class.
float m_growingFitInitialLength
The first step distance.
pandora::CartesianVector GetGlobalMinLayerPosition() const
Get global position corresponding to the fit result in minimum fit layer.
static float GetWirePitch(const pandora::Pandora &pandora, const pandora::HitType view, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
SortByDistanceToPoint class.
unsigned int m_hitThresholdForSpine
The hit threshold for a significant spine.
void CollectConnectedHits(const pandora::CaloHitList &collectedHits, const pandora::CartesianVector &extrapolatedStartPosition, const pandora::CartesianVector &extrapolatedDirection, pandora::CartesianPointVector &runningFitPositionVector, pandora::CaloHitList &showerSpineHitList) const
Add to the shower spine the connecting hits.
pandora::CartesianVector GetGlobalMaxLayerDirection() const
Get global direction corresponding to the fit result in maximum fit layer.
float m_growingFitSegmentLength
The standard step distance.
static float GetClosestDistance(const pandora::CaloHit *const pThisCaloHit, const pandora::CaloHitList &caloHitList)
Find the smallest separation between a hit and a list of hits, with the consideration of their hit wi...
void GetLocalPosition(const pandora::CartesianVector &position, float &rL, float &rT) const
Get local sliding fit coordinates for a given global position.
pandora::CartesianVector GetGlobalMaxLayerPosition() const
Get global position corresponding to the fit result in maximum fit layer.
TwoDSlidingFitResult class.
unsigned int m_localSlidingFitWindow
The standard sliding fit window for spine fits.