Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
HitWidthClusterMergingAlgorithm.cc
Go to the documentation of this file.
1
9
11
15
16using namespace pandora;
17
18namespace lar_content
19{
20
22 m_maxConstituentHitWidth(0.5f),
23 m_hitWidthScalingFactor(1.f),
24 m_fittingWeight(20.f),
25 m_minClusterWeight(0.5f),
26 m_maxXMergeDistance(5.f),
27 m_maxZMergeDistance(2.f),
28 m_minMergeCosOpeningAngle(0.97f),
29 m_minDirectionDeviationCosAngle(0.9f),
30 m_minClusterSparseness(0.3f)
31{
32}
33
34//------------------------------------------------------------------------------------------------------------------------------------------
35
36void HitWidthClusterMergingAlgorithm::GetListOfCleanClusters(const ClusterList *const pClusterList, ClusterVector &clusterVector) const
37{
38 // clear map if already full i.e. from other view clustering
39 if (!m_clusterToParametersMap.empty())
41
42 for (const Cluster *const pCluster : *pClusterList)
43 {
44 // the original cluster weight, with no hit scaling or hit padding
46 continue;
47
48 const unsigned int numberOfProposedConstituentHits(
50
51 if (numberOfProposedConstituentHits == 0)
52 continue;
53
54 // clusterSparseness [0 -> 1] where a higher value indicates sparseness
55 const float clusterSparseness(1.f - (static_cast<float>(pCluster->GetNCaloHits()) / static_cast<float>(numberOfProposedConstituentHits)));
56
57 if (clusterSparseness < m_minClusterSparseness)
58 continue;
59
60 m_clusterToParametersMap.insert(std::pair<const Cluster *, LArHitWidthHelper::ClusterParameters>(
62
63 clusterVector.push_back(pCluster);
64 }
65
66 std::sort(clusterVector.begin(), clusterVector.end(), LArHitWidthHelper::SortByHigherXExtrema(m_clusterToParametersMap));
67}
68
69//------------------------------------------------------------------------------------------------------------------------------------------
70
72{
73 // ATTN this method assumes that clusters have been sorted by extremal x position (low higherXExtrema -> high higherXExtrema)
74 for (ClusterVector::const_iterator iterCurrentCluster = clusterVector.begin(); iterCurrentCluster != clusterVector.end(); ++iterCurrentCluster)
75 {
76 const Cluster *const pCurrentCluster = *iterCurrentCluster;
77 const LArHitWidthHelper::ClusterParameters &currentClusterParameters(
79
80 for (ClusterVector::const_iterator iterTestCluster = iterCurrentCluster; iterTestCluster != clusterVector.end(); ++iterTestCluster)
81 {
82 if (iterCurrentCluster == iterTestCluster)
83 continue;
84
85 const Cluster *const pTestCluster = *iterTestCluster;
86 const LArHitWidthHelper::ClusterParameters &testClusterParameters(
88
89 if (!this->AreClustersAssociated(currentClusterParameters, testClusterParameters))
90 continue;
91
92 clusterAssociationMap[pCurrentCluster].m_forwardAssociations.insert(pTestCluster);
93 clusterAssociationMap[pTestCluster].m_backwardAssociations.insert(pCurrentCluster);
94 }
95 }
96
97 this->RemoveShortcutAssociations(clusterVector, clusterAssociationMap);
98}
99
100//------------------------------------------------------------------------------------------------------------------------------------------
101
102bool HitWidthClusterMergingAlgorithm::IsExtremalCluster(const bool isForward, const Cluster *const pCurrentCluster, const Cluster *const pTestCluster) const
103{
104 //ATTN - cannot use map since higherXExtrema may have changed during merging
105 const LArHitWidthHelper::ConstituentHitVector currentConstituentHitVector(
107 const LArHitWidthHelper::ConstituentHitVector testConstituentHitVector(
109 const CartesianVector currentHigherXExtrema(LArHitWidthHelper::GetExtremalCoordinatesHigherX(currentConstituentHitVector));
110 const CartesianVector testHigherXExtrema(LArHitWidthHelper::GetExtremalCoordinatesHigherX(testConstituentHitVector));
111 float currentMaxX(currentHigherXExtrema.GetX()), testMaxX(testHigherXExtrema.GetX());
112
113 if (isForward)
114 {
115 if (std::fabs(testMaxX - currentMaxX) > std::numeric_limits<float>::epsilon())
116 return (testMaxX > currentMaxX);
117 }
118 else
119 {
120 if (std::fabs(testMaxX - currentMaxX) > std::numeric_limits<float>::epsilon())
121 return (testMaxX < currentMaxX);
122 }
123
124 return LArClusterHelper::SortByNHits(pTestCluster, pCurrentCluster);
125}
126
127//------------------------------------------------------------------------------------------------------------------------------------------
128
130 const LArHitWidthHelper::ClusterParameters &currentFitParameters, const LArHitWidthHelper::ClusterParameters &testFitParameters) const
131{
132 // check cluster extrema are not too far away in x
133 if (testFitParameters.GetLowerXExtrema().GetX() > (currentFitParameters.GetHigherXExtrema().GetX() + m_maxXMergeDistance))
134 return false;
135
136 // check cluster extrema are not too far away in z
137 if (testFitParameters.GetLowerXExtrema().GetZ() > (currentFitParameters.GetHigherXExtrema().GetZ() + m_maxZMergeDistance) ||
138 testFitParameters.GetLowerXExtrema().GetZ() < (currentFitParameters.GetHigherXExtrema().GetZ() - m_maxZMergeDistance))
139 {
140 return false;
141 }
142
143 // find appropriate test merging point (may be different to lowerXExtrema when hits overlap)
144 CartesianVector testMergePoint(0.f, 0.f, 0.f);
145 if (testFitParameters.GetLowerXExtrema().GetX() < currentFitParameters.GetHigherXExtrema().GetX())
146 {
147 this->FindClosestPointToPosition(currentFitParameters.GetHigherXExtrema(), testFitParameters.GetConstituentHitVector(), testMergePoint);
148
149 // check closeness in z is maintained
150 if (testMergePoint.GetZ() > (currentFitParameters.GetHigherXExtrema().GetZ() + m_maxZMergeDistance) ||
151 testMergePoint.GetZ() < (currentFitParameters.GetHigherXExtrema().GetZ() - m_maxZMergeDistance))
152 {
153 return false;
154 }
155 }
156 else
157 {
158 testMergePoint = testFitParameters.GetLowerXExtrema();
159 }
160
161 CartesianVector currentClusterDirection(0.f, 0.f, 0.f), testClusterDirection(0.f, 0.f, 0.f);
162
163 try
164 {
165 this->GetClusterDirection(currentFitParameters.GetConstituentHitVector(), currentClusterDirection,
166 currentFitParameters.GetHigherXExtrema(), m_fittingWeight);
167 this->GetClusterDirection(testFitParameters.GetConstituentHitVector(), testClusterDirection, testMergePoint, m_fittingWeight);
168 }
169 catch (const StatusCodeException &)
170 {
171 return false;
172 }
173
174 // check clusters have a similar direction
175 if (currentClusterDirection.GetCosOpeningAngle(testClusterDirection) < m_minMergeCosOpeningAngle)
176 return false;
177
178 // check that the new direction is consistent with the old clusters
179 LArHitWidthHelper::ConstituentHitVector newConstituentHitVector(currentFitParameters.GetConstituentHitVector());
180 newConstituentHitVector.insert(newConstituentHitVector.end(), testFitParameters.GetConstituentHitVector().begin(),
181 testFitParameters.GetConstituentHitVector().end());
182
183 const CartesianVector midpoint((currentFitParameters.GetHigherXExtrema() + testMergePoint) * 0.5);
184 CartesianVector newClusterDirection(0.f, 0.f, 0.f);
185
186 try
187 {
188 this->GetClusterDirection(newConstituentHitVector, newClusterDirection, midpoint, m_fittingWeight);
189 }
190 catch (const StatusCodeException &)
191 {
192 return false;
193 }
194
195 if (newClusterDirection.GetCosOpeningAngle(currentClusterDirection) < m_minDirectionDeviationCosAngle ||
196 newClusterDirection.GetCosOpeningAngle(testClusterDirection) < m_minDirectionDeviationCosAngle)
197 {
198 return false;
199 }
200
201 return true;
202}
203
204//------------------------------------------------------------------------------------------------------------------------------------------
205
207 const LArHitWidthHelper::ConstituentHitVector &constituentHitVector, CartesianVector &closestPoint) const
208{
209 float minDistanceSquared(std::numeric_limits<float>::max());
210 for (const LArHitWidthHelper::ConstituentHit &constituentHit : constituentHitVector)
211 {
212 const CartesianVector &hitPosition(constituentHit.GetPositionVector());
213 const float separationDistanceSquared(hitPosition.GetDistanceSquared(position));
214
215 if (separationDistanceSquared < minDistanceSquared)
216 {
217 minDistanceSquared = separationDistanceSquared;
218 closestPoint = hitPosition;
219 }
220 }
221}
222
223//------------------------------------------------------------------------------------------------------------------------------------------
224
226 CartesianVector &direction, const CartesianVector &fitReferencePoint, const float fittingWeight) const
227{
228 float weightSum(0.f), weightedLSum(0.f), weightedTSum(0.f);
229 bool isLConstant(true), isTConstant(true);
230
231 // get fitting subset vector
232 LArHitWidthHelper::ConstituentHitVector constituentHitSubsetVector;
233 this->GetConstituentHitSubsetVector(constituentHitVector, fitReferencePoint, fittingWeight, constituentHitSubsetVector);
234
235 // determine the fitting axes
236 CartesianVector axisDirection(0.f, 0.f, 0.f), orthoDirection(0.f, 0.f, 0.f);
237 this->GetFittingAxes(constituentHitSubsetVector, axisDirection, orthoDirection);
238
239 // the comparison to check if constituent hit positions are constant in rL or rT (would lead to a division by zero)
240 float firstHitL(0.f), firstHitT(0.f);
241 this->GetFittingCoordinates(axisDirection, constituentHitSubsetVector.begin()->GetPositionVector(), firstHitL, firstHitT);
242
243 for (const LArHitWidthHelper::ConstituentHit &constituentHit : constituentHitSubsetVector)
244 {
245 const float hitWeight(constituentHit.GetHitWidth());
246 float rL(0.f), rT(0.f);
247 this->GetFittingCoordinates(axisDirection, constituentHit.GetPositionVector(), rL, rT);
248
249 if (std::fabs(firstHitL - rL) > std::numeric_limits<float>::epsilon())
250 isLConstant = false;
251
252 if (std::fabs(firstHitT - rT) > std::numeric_limits<float>::epsilon())
253 isTConstant = false;
254
255 weightedLSum += rL * hitWeight;
256 weightedTSum += rT * hitWeight;
257 weightSum += hitWeight;
258 }
259
260 if (weightSum < std::numeric_limits<float>::epsilon())
261 {
262 std::cout << "HitWidthClusterMergingAlgorithm::GetWeightedGradient - hit weight in fit is negative or equivalent to zero" << std::endl;
263 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
264 }
265
266 // return ortho direction for a cluster with constant rL
267 if (isLConstant)
268 {
269 // ATTN direction convention is to point in direction of increasing x
270 direction = (orthoDirection.GetX() < 0.f) ? orthoDirection * (-1.f) : orthoDirection;
271 return;
272 }
273
274 // return axis direction for a cluster with constant rT
275 if (isTConstant)
276 {
277 // ATTN direction convention is to point in direction of increasing x
278 direction = (axisDirection.GetX() < 0.f) ? axisDirection * (-1.f) : axisDirection;
279 return;
280 }
281
282 const float weightedLMean(weightedLSum / weightSum), weightedTMean(weightedTSum / weightSum);
283 float numerator(0.f), denominator(0.f);
284
285 for (const LArHitWidthHelper::ConstituentHit &constituentHit : constituentHitSubsetVector)
286 {
287 const float hitWeight(constituentHit.GetHitWidth());
288 float rL(0.f), rT(0.f);
289 this->GetFittingCoordinates(axisDirection, constituentHit.GetPositionVector(), rL, rT);
290
291 numerator += hitWeight * (rL - weightedLMean) * (rT - weightedTMean);
292 denominator += hitWeight * pow(rL - weightedLMean, 2);
293 }
294
295 const float gradient(numerator / denominator);
296
297 // change coordinates to z=mx+c fit and normalise
298 this->GetGlobalDirection(axisDirection, gradient, direction);
299
300 // ATTN direction convention is to point in direction of increasing x
301 if (direction.GetX() < 0.f)
302 direction *= -1.f;
303}
304
305//------------------------------------------------------------------------------------------------------------------------------------------
306
308 const CartesianVector &fitReferencePoint, const float fittingWeight, LArHitWidthHelper::ConstituentHitVector &constituentHitSubsetVector) const
309{
310 LArHitWidthHelper::ConstituentHitVector sortedConstituentHitVector(constituentHitVector);
311
312 // sort hits with respect to their distance to the fitReferencePoint (closest -> furthest)
313 std::sort(sortedConstituentHitVector.begin(), sortedConstituentHitVector.end(),
315
316 float weightCount(0.f);
317 for (const LArHitWidthHelper::ConstituentHit &constituentHit : sortedConstituentHitVector)
318 {
319 constituentHitSubsetVector.push_back(constituentHit);
320
321 weightCount += constituentHit.GetHitWidth();
322
323 if (weightCount > fittingWeight)
324 break;
325 }
326}
327
328//------------------------------------------------------------------------------------------------------------------------------------------
329
331 CartesianVector &axisDirection, CartesianVector &orthoDirection) const
332{
333 CartesianPointVector constituentHitSubsetPositionVector(LArHitWidthHelper::GetConstituentHitPositionVector(constituentHitSubsetVector));
334
335 if (constituentHitSubsetPositionVector.size() < 2)
336 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
337
338 CartesianVector centroid(0.f, 0.f, 0.f);
340 LArPcaHelper::EigenValues eigenValues(0.f, 0.f, 0.f);
341 LArPcaHelper::RunPca(constituentHitSubsetPositionVector, centroid, eigenValues, eigenVecs);
342
343 axisDirection = eigenVecs.at(0);
344
345 // ATTN fitting convention is to point in direction of increasing z
346 if (axisDirection.GetZ() < 0.f)
347 axisDirection *= -1.f;
348
349 // Use y-axis to generate an orthogonal axis (assuming that cluster occupies x-z plane)
350 const CartesianVector yAxis(0.f, 1.f, 0.f);
351 orthoDirection = yAxis.GetCrossProduct(axisDirection).GetUnitVector();
352}
353
354//------------------------------------------------------------------------------------------------------------------------------------------
355
357 const CartesianVector &axisDirection, const CartesianVector &constituentHitPosition, float &rL, float &rT) const
358{
359 // axisDirection is in positive z by convention so use opening angle to obtain coordinates in rotated frame
360 const CartesianVector xAxis(1.f, 0.f, 0.f);
361 const float openingAngle(axisDirection.GetOpeningAngle(xAxis)), c(std::cos(openingAngle)), s(std::sin(openingAngle));
362
363 rL = (c * constituentHitPosition.GetX()) + (s * constituentHitPosition.GetZ());
364 rT = (c * constituentHitPosition.GetZ()) - (s * constituentHitPosition.GetX());
365}
366
367//------------------------------------------------------------------------------------------------------------------------------------------
368
369void HitWidthClusterMergingAlgorithm::GetGlobalDirection(const CartesianVector &axisDirection, const float gradient, CartesianVector &globalDirection) const
370{
371 const CartesianVector xAxis(1.f, 0.f, 0.f);
372 const float openingAngle(axisDirection.GetOpeningAngle(xAxis)), c(std::cos(openingAngle)), s(std::sin(openingAngle));
373 const float deltaL(1.f), deltaT(gradient);
374
375 const float x = (c * deltaL) - (s * deltaT);
376 const float z = (c * deltaT) + (s * deltaL);
377
378 globalDirection.SetValues(x, 0.f, z);
379 globalDirection = globalDirection.GetUnitVector();
380}
381
382//------------------------------------------------------------------------------------------------------------------------------------------
383
385{
386 // Create temporary map so can delete elements whilst still iterating over them
387 ClusterAssociationMap tempMap(clusterAssociationMap);
388
389 for (const Cluster *const pCluster : clusterVector)
390 {
391 const ClusterAssociationMap::const_iterator primaryMapIter = clusterAssociationMap.find(pCluster);
392
393 if (primaryMapIter == clusterAssociationMap.end())
394 continue;
395
396 // put ClusterSet into ClusterVector
397 ClusterVector primaryForwardAssociations(
398 primaryMapIter->second.m_forwardAssociations.begin(), primaryMapIter->second.m_forwardAssociations.end());
399 std::sort(primaryForwardAssociations.begin(), primaryForwardAssociations.end(), LArClusterHelper::SortByNHits);
400
401 // remove primary clusters that are present in secondary associations of other primary clusters
402 for (const Cluster *const pConsideredCluster : primaryForwardAssociations)
403 {
404 for (const Cluster *const pPrimaryCluster : primaryForwardAssociations)
405 {
406 if (pConsideredCluster == pPrimaryCluster)
407 continue;
408
409 const ClusterAssociationMap::const_iterator secondaryMapIter = clusterAssociationMap.find(pPrimaryCluster);
410
411 // if primary cluster has no associations (this shouldn't ever be the case)
412 if (secondaryMapIter == clusterAssociationMap.end())
413 continue;
414
415 const ClusterSet &secondaryForwardAssociations(secondaryMapIter->second.m_forwardAssociations);
416
417 if (secondaryForwardAssociations.find(pConsideredCluster) != secondaryForwardAssociations.end())
418 {
419 ClusterSet &tempPrimaryForwardAssociations(tempMap.find(pCluster)->second.m_forwardAssociations);
420 const ClusterSet::const_iterator forwardAssociationToRemove(tempPrimaryForwardAssociations.find(pConsideredCluster));
421
422 // if association has already been removed
423 if (forwardAssociationToRemove == tempPrimaryForwardAssociations.end())
424 continue;
425
426 ClusterSet &tempPrimaryBackwardAssociations(tempMap.find(pConsideredCluster)->second.m_backwardAssociations);
427 const ClusterSet::const_iterator backwardAssociationToRemove(tempPrimaryBackwardAssociations.find(pCluster));
428
429 // if association has already been removed
430 if (backwardAssociationToRemove == tempPrimaryBackwardAssociations.end())
431 continue;
432
433 tempPrimaryForwardAssociations.erase(forwardAssociationToRemove);
434 tempPrimaryBackwardAssociations.erase(backwardAssociationToRemove);
435 }
436 }
437 }
438 }
439
440 clusterAssociationMap = tempMap;
441}
442
443//------------------------------------------------------------------------------------------------------------------------------------------
444
446{
447 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "FittingWeight", m_fittingWeight));
448
450 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinClusterWeight", m_minClusterWeight));
451
453 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxXMergeDistance", m_maxXMergeDistance));
454
456 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxZMergeDistance", m_maxZMergeDistance));
457
458 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
459 XmlHelper::ReadValue(xmlHandle, "MinMergeCosOpeningAngle", m_minMergeCosOpeningAngle));
460
461 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
462 XmlHelper::ReadValue(xmlHandle, "MinDirectionDeviationCosAngle", m_minDirectionDeviationCosAngle));
463
465 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxConstituentHitWidth", m_maxConstituentHitWidth));
466
468 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "HitWidthScalingFactor", m_hitWidthScalingFactor));
469
471 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinClusterSparseness", m_minClusterSparseness));
472
474}
475
476} // namespace lar_content
Grouping of header files for many classes of use in particle flow algorithms.
Header file for the hit width cluster merging algorithm class.
Header file for the cluster helper class.
Header file for the geometry helper class.
Header file for the principal curve analysis helper class.
#define PANDORA_RETURN_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
Definition StatusCodes.h:31
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
std::unordered_map< const pandora::Cluster *, ClusterAssociation > ClusterAssociationMap
void GetListOfCleanClusters(const pandora::ClusterList *const pClusterList, pandora::ClusterVector &clusterVector) const
Populate cluster vector with subset of cluster list, containing clusters judged to be clean.
float m_minClusterSparseness
The threshold sparseness of a cluster to be considered in the merging process.
float m_minMergeCosOpeningAngle
The minimum cosine opening angle of the directions of associated clusters.
bool AreClustersAssociated(const LArHitWidthHelper::ClusterParameters &currentClusterParameters, const LArHitWidthHelper::ClusterParameters &testClusterParameters) const
Determine whether two clusters are associated.
void GetConstituentHitSubsetVector(const LArHitWidthHelper::ConstituentHitVector &constituentHitVector, const pandora::CartesianVector &fitReferencePoint, const float fittingWeight, LArHitWidthHelper::ConstituentHitVector &constituentHitSubsetVector) const
Obtain a vector of the minimum number of hits closest to a reference point that exceed a given weight...
float m_maxXMergeDistance
The maximum x distance between merging points of associated clusters, units cm.
void RemoveShortcutAssociations(const pandora::ClusterVector &clusterVector, ClusterAssociationMap &clusterAssociationMap) const
Remove 'shortcut' associations from the cluster association map.
void FindClosestPointToPosition(const pandora::CartesianVector &position, const LArHitWidthHelper::ConstituentHitVector &constituentHitVector, pandora::CartesianVector &closestPoint) const
Determine the position of the constituent hit that lies closest to a specified position.
float m_maxConstituentHitWidth
The maximum hit width of a constituent hit of broken up hit, units cm.
float m_minClusterWeight
The threshold hit weight of the original, unscaled cluster to be considered in the merging process.
void GetFittingCoordinates(const pandora::CartesianVector &axisDirection, const pandora::CartesianVector &constituentHitPosition, float &rL, float &rT) const
Translate from (x, y, z) coordinates to (rL, rT) coordinates.
void GetGlobalDirection(const pandora::CartesianVector &axisDirection, const float gradient, pandora::CartesianVector &globalDirection) const
Translate a gradient in the fitting coordinate frame to a direction vector in the detector frame.
void PopulateClusterAssociationMap(const pandora::ClusterVector &clusterVector, ClusterAssociationMap &clusterAssociationMap) const
Populate the cluster association map.
float m_fittingWeight
The maximum hit weight considered in the least squared fit.
float m_maxZMergeDistance
The maximum z distance between merging points of associated clusters, units cm.
LArHitWidthHelper::ClusterToParametersMap m_clusterToParametersMap
The map [cluster -> cluster parameters].
float m_hitWidthScalingFactor
The scaling factor of the hit widths.
bool IsExtremalCluster(const bool isForward, const pandora::Cluster *const pCurrentCluster, const pandora::Cluster *const pTestCluster) const
Determine which of two clusters is extremal.
void GetFittingAxes(const LArHitWidthHelper::ConstituentHitVector &constituentHitSubsetVector, pandora::CartesianVector &axisDirection, pandora::CartesianVector &orthoDirection) const
Obtain the axes of the fitting frame.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
void GetClusterDirection(const LArHitWidthHelper::ConstituentHitVector &constituentHitVector, pandora::CartesianVector &direction, const pandora::CartesianVector &fitReferencePoint, const float fittingWeight) const
Determine the cluster direction at a reference point by performing a weighted least squared fit to th...
float m_minDirectionDeviationCosAngle
The minimum cosine opening angle of the direction of and associated cluster before and after merge.
static bool SortByNHits(const pandora::Cluster *const pLhs, const pandora::Cluster *const pRhs)
Sort clusters by number of hits, then layer span, then inner layer, then position,...
const pandora::CartesianVector & GetHigherXExtrema() const
Returns the higher x extremal point of the constituent hits.
const pandora::CartesianVector & GetLowerXExtrema() const
Returns the lower x extremal point of the constituent hits.
const ConstituentHitVector & GetConstituentHitVector() const
Returns the vector of constituent hits.
static unsigned int GetNProposedConstituentHits(const pandora::Cluster *const pCluster, const float maxConstituentHitWidth, const float hitWidthScalingFactor)
Return the number of constituent hits that a given cluster would be broken into.
std::vector< ConstituentHit > ConstituentHitVector
static pandora::CartesianPointVector GetConstituentHitPositionVector(const ConstituentHitVector &constituentHitVector)
Obtain a vector of the contituent hit central positions.
static pandora::CartesianVector GetExtremalCoordinatesHigherX(const ConstituentHitVector &constituentHitVector)
Return the higher x extremal point of the constituent hits.
static const ClusterParameters & GetClusterParameters(const pandora::Cluster *const pCluster, const ClusterToParametersMap &clusterToParametersMap)
Return the cluster parameters of a given cluster, exception thrown if not found in map [cluster -> cl...
static float GetOriginalTotalClusterWeight(const pandora::Cluster *const pCluster)
Sum the widths of the original, unscaled hits contained within a cluster.
static ConstituentHitVector GetConstituentHits(const pandora::Cluster *const pCluster, const float maxConstituentHitWidth, const float hitWidthScalingFactor, const bool isUniform)
Break up the cluster hits into constituent hits.
std::vector< pandora::CartesianVector > EigenVectors
static void RunPca(const T &t, pandora::CartesianVector &centroid, EigenValues &outputEigenValues, EigenVectors &outputEigenVectors)
Run principal component analysis using input calo hits (TPC_VIEW_U,V,W or TPC_3D; all treated as 3D p...
CartesianVector class.
void SetValues(float x, float y, float z)
Set the values of cartesian vector components.
float GetCosOpeningAngle(const CartesianVector &rhs) const
Get the cosine of the opening angle of the cartesian vector with respect to a second cartesian vector...
float GetX() const
Get the cartesian x coordinate.
float GetDistanceSquared(const CartesianVector &rhs) const
Get the distance squared of a cartesian vector with respect to a second cartesian vector.
CartesianVector GetUnitVector() const
Get a unit vector in the direction of the cartesian vector.
float GetZ() const
Get the cartesian z coordinate.
CartesianVector GetCrossProduct(const CartesianVector &rhs) const
Get the cross product of the cartesian vector with a second cartesian vector.
float GetOpeningAngle(const CartesianVector &rhs) const
Get the opening angle of the cartesian vector with respect to a second cartesian vector.
Cluster class.
Definition Cluster.h:31
StatusCodeException class.
static StatusCode ReadValue(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, T &t)
Read a value from an xml element.
Definition XmlHelper.h:136
std::vector< const Cluster * > ClusterVector
MANAGED_CONTAINER< const Cluster * > ClusterList
std::vector< CartesianVector > CartesianPointVector
std::unordered_set< const Cluster * > ClusterSet
StatusCode
The StatusCode enum.