Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
SplitShowersTool.cc
Go to the documentation of this file.
1
10
14
16
18
19using namespace pandora;
20
21namespace lar_content
22{
23
25 m_nCommonClusters(2),
26 m_minMatchedFraction(0.25f),
27 m_minMatchedSamplingPoints(40),
28 m_checkClusterProximities(true),
29 m_maxClusterSeparation(25.f),
30 m_checkClusterVertexRelations(true),
31 m_minVertexLongitudinalDistance(-2.5f),
32 m_maxVertexLongitudinalDistance(20.f),
33 m_maxVertexTransverseDistance(1.5f),
34 m_vertexAngularAllowance(3.f),
35 m_maxVertexAssociations(1),
36 m_checkClusterSplitPositions(false),
37 m_vetoMergeXDifference(2.f),
38 m_vetoMergeXOverlap(2.f)
39{
40}
41
42//------------------------------------------------------------------------------------------------------------------------------------------
43
44bool SplitShowersTool::Run(ThreeViewShowersAlgorithm *const pAlgorithm, TensorType &overlapTensor)
45{
47 std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
48
49 ClusterMergeMap clusterMergeMap;
50 this->FindSplitShowers(pAlgorithm, overlapTensor, clusterMergeMap);
51
52 return this->ApplyChanges(pAlgorithm, clusterMergeMap);
53}
54
55//------------------------------------------------------------------------------------------------------------------------------------------
56
57void SplitShowersTool::FindSplitShowers(ThreeViewShowersAlgorithm *const pAlgorithm, const TensorType &overlapTensor, ClusterMergeMap &clusterMergeMap) const
58{
59 ClusterSet usedClusters;
60 ClusterVector sortedKeyClusters;
61 overlapTensor.GetSortedKeyClusters(sortedKeyClusters);
62
63 for (const Cluster *const pKeyCluster : sortedKeyClusters)
64 {
65 if (!pKeyCluster->IsAvailable())
66 continue;
67
68 unsigned int nU(0), nV(0), nW(0);
69 TensorType::ElementList elementList;
70 overlapTensor.GetConnectedElements(pKeyCluster, true, elementList, nU, nV, nW);
71
72 if (nU * nV * nW < 2)
73 continue;
74
75 for (TensorType::ElementList::const_iterator eIter = elementList.begin(); eIter != elementList.end(); ++eIter)
76 {
77 if (!this->PassesElementCuts(eIter, usedClusters))
78 continue;
79
80 IteratorList iteratorList;
81 this->SelectTensorElements(eIter, elementList, usedClusters, iteratorList);
82
83 if (iteratorList.size() < 2)
84 continue;
85
86 this->FindShowerMerges(pAlgorithm, iteratorList, usedClusters, clusterMergeMap);
87 }
88 }
89}
90
91//------------------------------------------------------------------------------------------------------------------------------------------
92
93bool SplitShowersTool::PassesElementCuts(TensorType::ElementList::const_iterator eIter, const ClusterSet &usedClusters) const
94{
95 if (usedClusters.count(eIter->GetClusterU()) || usedClusters.count(eIter->GetClusterV()) || usedClusters.count(eIter->GetClusterW()))
96 return false;
97
98 if (eIter->GetOverlapResult().GetMatchedFraction() < m_minMatchedFraction)
99 return false;
100
101 if (eIter->GetOverlapResult().GetNMatchedSamplingPoints() < m_minMatchedSamplingPoints)
102 return false;
103
104 return true;
105}
106
107//------------------------------------------------------------------------------------------------------------------------------------------
108
109void SplitShowersTool::SelectTensorElements(TensorType::ElementList::const_iterator eIter, const TensorType::ElementList &elementList,
110 const ClusterSet &usedClusters, IteratorList &iteratorList) const
111{
112 iteratorList.push_back(eIter);
113
114 for (TensorType::ElementList::const_iterator eIter2 = elementList.begin(); eIter2 != elementList.end(); ++eIter2)
115 {
116 if (eIter == eIter2)
117 continue;
118
119 if (!this->PassesElementCuts(eIter2, usedClusters))
120 continue;
121
122 for (IteratorList::const_iterator iIter = iteratorList.begin(); iIter != iteratorList.end(); ++iIter)
123 {
124 if ((*iIter) == eIter2)
125 continue;
126
127 unsigned int nMatchedClusters(0);
128
129 if ((*iIter)->GetClusterU() == eIter2->GetClusterU())
130 ++nMatchedClusters;
131
132 if ((*iIter)->GetClusterV() == eIter2->GetClusterV())
133 ++nMatchedClusters;
134
135 if ((*iIter)->GetClusterW() == eIter2->GetClusterW())
136 ++nMatchedClusters;
137
138 if (m_nCommonClusters == nMatchedClusters)
139 {
140 iteratorList.push_back(eIter2);
141 return;
142 }
143 }
144 }
145}
146
147//------------------------------------------------------------------------------------------------------------------------------------------
148
150 ClusterSet &usedClusters, ClusterMergeMap &clusterMergeMap) const
151{
152 for (IteratorList::const_iterator iIter1 = iteratorList.begin(), iIter1End = iteratorList.end(); iIter1 != iIter1End; ++iIter1)
153 {
154 for (IteratorList::const_iterator iIter2 = iIter1; iIter2 != iIter1End; ++iIter2)
155 {
156 try
157 {
158 if (iIter1 == iIter2)
159 continue;
160
161 const TensorType::Element &element1(*(*iIter1));
162 const TensorType::Element &element2(*(*iIter2));
163
164 ClusterList clusterListU(1, element1.GetClusterU());
165 if (element1.GetClusterU() != element2.GetClusterU())
166 clusterListU.push_back(element2.GetClusterU());
167
168 ClusterList clusterListV(1, element1.GetClusterV());
169 if (element1.GetClusterV() != element2.GetClusterV())
170 clusterListV.push_back(element2.GetClusterV());
171
172 ClusterList clusterListW(1, element1.GetClusterW());
173 if (element1.GetClusterW() != element2.GetClusterW())
174 clusterListW.push_back(element2.GetClusterW());
175
176 const unsigned int nClustersU(clusterListU.size()), nClustersV(clusterListV.size()), nClustersW(clusterListW.size());
177 const unsigned int nClustersProduct(nClustersU * nClustersV * nClustersW);
178
179 if (((1 == m_nCommonClusters) && (4 != nClustersProduct)) || ((2 == m_nCommonClusters) && (2 != nClustersProduct)))
180 throw StatusCodeException(STATUS_CODE_FAILURE);
181
182 if ((1 == m_nCommonClusters) && !((2 == nClustersU) || (2 == nClustersV) || (2 == nClustersW)))
183 throw StatusCodeException(STATUS_CODE_FAILURE);
184
186 (!this->CheckClusterProximities(pAlgorithm, clusterListU) || !this->CheckClusterProximities(pAlgorithm, clusterListV) ||
187 !this->CheckClusterProximities(pAlgorithm, clusterListW)))
188 {
189 continue;
190 }
191
192 if (m_checkClusterVertexRelations && (!this->CheckClusterVertexRelations(pAlgorithm, clusterListU) ||
193 !this->CheckClusterVertexRelations(pAlgorithm, clusterListV) ||
194 !this->CheckClusterVertexRelations(pAlgorithm, clusterListW)))
195 {
196 continue;
197 }
198
199 if (m_checkClusterSplitPositions && !this->CheckClusterSplitPositions(pAlgorithm, clusterListU, clusterListV, clusterListW))
200 {
201 continue;
202 }
203
204 this->SpecifyClusterMerges(pAlgorithm, clusterListU, clusterMergeMap);
205 this->SpecifyClusterMerges(pAlgorithm, clusterListV, clusterMergeMap);
206 this->SpecifyClusterMerges(pAlgorithm, clusterListW, clusterMergeMap);
207
208 usedClusters.insert(clusterListU.begin(), clusterListU.end());
209 usedClusters.insert(clusterListV.begin(), clusterListV.end());
210 usedClusters.insert(clusterListW.begin(), clusterListW.end());
211 }
212 catch (StatusCodeException &)
213 {
214 }
215 }
216 }
217}
218
219//------------------------------------------------------------------------------------------------------------------------------------------
220
221bool SplitShowersTool::CheckClusterProximities(ThreeViewShowersAlgorithm * /*const pAlgorithm*/, const ClusterList &clusterList) const
222{
223 if (1 == clusterList.size())
224 return true;
225
226 if (2 != clusterList.size())
227 throw StatusCodeException(STATUS_CODE_FAILURE);
228
229 const Cluster *const pCluster1(*(clusterList.begin()));
230 const Cluster *const pCluster2(*(++(clusterList.begin())));
231
232 const float outer12(LArClusterHelper::GetClosestDistance(pCluster1->GetCentroid(pCluster1->GetOuterPseudoLayer()), pCluster2));
233 const float outer21(LArClusterHelper::GetClosestDistance(pCluster2->GetCentroid(pCluster2->GetOuterPseudoLayer()), pCluster1));
234 const float inner12(LArClusterHelper::GetClosestDistance(pCluster1->GetCentroid(pCluster1->GetInnerPseudoLayer()), pCluster2));
235 const float inner21(LArClusterHelper::GetClosestDistance(pCluster2->GetCentroid(pCluster2->GetInnerPseudoLayer()), pCluster1));
236
237 if ((outer12 > m_maxClusterSeparation) && (outer21 > m_maxClusterSeparation) && (inner12 > m_maxClusterSeparation) && (inner21 > m_maxClusterSeparation))
238 return false;
239
240 return true;
241}
242
243//------------------------------------------------------------------------------------------------------------------------------------------
244
246{
247 const VertexList *pVertexList(NULL);
248 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*pAlgorithm, pVertexList));
249 const Vertex *const pVertex(
250 ((pVertexList->size() == 1) && (VERTEX_3D == (*(pVertexList->begin()))->GetVertexType())) ? *(pVertexList->begin()) : NULL);
251
252 if (NULL == pVertex)
253 return true;
254
255 unsigned int nVertexAssociations(0);
256
257 for (ClusterList::const_iterator iter = clusterList.begin(), iterEnd = clusterList.end(); iter != iterEnd; ++iter)
258 {
259 try
260 {
261 const HitType hitType(LArClusterHelper::GetClusterHitType(*iter));
262 const CartesianVector vertex2D(LArGeometryHelper::ProjectPosition(this->GetPandora(), pVertex->GetPosition(), hitType));
263 const LArPointingCluster pointingCluster(pAlgorithm->GetCachedSlidingFitResult(*iter).GetShowerFitResult());
264
271 {
272 ++nVertexAssociations;
273 }
274 }
275 catch (StatusCodeException &)
276 {
277 }
278 }
279
280 if (nVertexAssociations > m_maxVertexAssociations)
281 return false;
282
283 return true;
284}
285
286//------------------------------------------------------------------------------------------------------------------------------------------
287
289 const ClusterList &clusterListV, const ClusterList &clusterListW) const
290{
291 const unsigned int nClustersU(clusterListU.size()), nClustersV(clusterListV.size()), nClustersW(clusterListW.size());
292 const unsigned int nClustersProduct(nClustersU * nClustersV * nClustersW);
293
294 if (2 == nClustersProduct)
295 return true;
296
297 const ClusterList &clusterList1((1 == nClustersU) ? clusterListV : clusterListU);
298 const ClusterList &clusterList2((1 == nClustersU) ? clusterListW : (1 == nClustersV) ? clusterListW : clusterListV);
299
300 if ((2 != clusterList1.size()) || (2 != clusterList2.size()))
301 throw StatusCodeException(STATUS_CODE_FAILURE);
302
303 float splitXPosition1(0.f), overlapX1(0.f);
304 this->GetSplitXDetails(pAlgorithm, *(clusterList1.begin()), *(++(clusterList1.begin())), splitXPosition1, overlapX1);
305
306 float splitXPosition2(0.f), overlapX2(0.f);
307 this->GetSplitXDetails(pAlgorithm, *(clusterList2.begin()), *(++(clusterList2.begin())), splitXPosition2, overlapX2);
308
309 if ((std::fabs(splitXPosition1 - splitXPosition2) < m_vetoMergeXDifference) && (overlapX1 < m_vetoMergeXOverlap) && (overlapX2 < m_vetoMergeXOverlap))
310 return false;
311
312 return true;
313}
314
315//------------------------------------------------------------------------------------------------------------------------------------------
316
317void SplitShowersTool::GetSplitXDetails(ThreeViewShowersAlgorithm *const pAlgorithm, const Cluster *const pClusterA,
318 const Cluster *const pClusterB, float &splitXPosition, float &overlapX) const
319{
320 const TwoDSlidingFitResult &fitResultA(pAlgorithm->GetCachedSlidingFitResult(pClusterA).GetShowerFitResult());
321 const TwoDSlidingFitResult &fitResultB(pAlgorithm->GetCachedSlidingFitResult(pClusterB).GetShowerFitResult());
322
323 const float minXA(std::min(fitResultA.GetGlobalMinLayerPosition().GetX(), fitResultA.GetGlobalMaxLayerPosition().GetX()));
324 const float maxXA(std::max(fitResultA.GetGlobalMinLayerPosition().GetX(), fitResultA.GetGlobalMaxLayerPosition().GetX()));
325 const float minXB(std::min(fitResultB.GetGlobalMinLayerPosition().GetX(), fitResultB.GetGlobalMaxLayerPosition().GetX()));
326 const float maxXB(std::max(fitResultB.GetGlobalMinLayerPosition().GetX(), fitResultB.GetGlobalMaxLayerPosition().GetX()));
327
328 FloatVector floatVector;
329 floatVector.push_back(minXA);
330 floatVector.push_back(maxXA);
331 floatVector.push_back(minXB);
332 floatVector.push_back(maxXB);
333 std::sort(floatVector.begin(), floatVector.end());
334
335 if (4 != floatVector.size())
336 throw StatusCodeException(STATUS_CODE_FAILURE);
337
338 splitXPosition = 0.5f * (floatVector.at(1) + floatVector.at(2));
339 overlapX = std::max(0.f, std::min(maxXA, maxXB) - std::max(minXA, minXB));
340}
341
342//------------------------------------------------------------------------------------------------------------------------------------------
343
344void SplitShowersTool::SpecifyClusterMerges(ThreeViewShowersAlgorithm *const pAlgorithm, const ClusterList &clusterList, ClusterMergeMap &clusterMergeMap) const
345{
346 if (1 == clusterList.size())
347 return;
348
349 if (2 != clusterList.size())
350 throw StatusCodeException(STATUS_CODE_FAILURE);
351
352 const Cluster *const pClusterA(*(clusterList.begin())), *const pClusterB(*(++(clusterList.begin())));
353 const TwoDSlidingFitResult &fitResultA(pAlgorithm->GetCachedSlidingFitResult(pClusterA).GetShowerFitResult());
354 const TwoDSlidingFitResult &fitResultB(pAlgorithm->GetCachedSlidingFitResult(pClusterB).GetShowerFitResult());
355
356 const float minXA(std::min(fitResultA.GetGlobalMinLayerPosition().GetX(), fitResultA.GetGlobalMaxLayerPosition().GetX()));
357 const float minXB(std::min(fitResultB.GetGlobalMinLayerPosition().GetX(), fitResultB.GetGlobalMaxLayerPosition().GetX()));
358
359 const Cluster *const pLowXCluster((minXA < minXB) ? pClusterA : pClusterB);
360 const Cluster *const pHighXCluster((minXA < minXB) ? pClusterB : pClusterA);
361 clusterMergeMap[pLowXCluster].push_back(pHighXCluster);
362}
363
364//------------------------------------------------------------------------------------------------------------------------------------------
365
366bool SplitShowersTool::ApplyChanges(ThreeViewShowersAlgorithm *const pAlgorithm, const ClusterMergeMap &clusterMergeMap) const
367{
368 ClusterMergeMap consolidatedMergeMap;
369
370 ClusterList clusterList;
371 for (const auto &mapEntry : clusterMergeMap)
372 clusterList.push_back(mapEntry.first);
373 clusterList.sort(LArClusterHelper::SortByNHits);
374
375 for (const Cluster *const pParentCluster : clusterList)
376 {
377 const ClusterList &daughterClusters(clusterMergeMap.at(pParentCluster));
378
379 for (const Cluster *const pDaughterCluster : daughterClusters)
380 {
381 if (consolidatedMergeMap.count(pDaughterCluster))
382 throw StatusCodeException(STATUS_CODE_FAILURE);
383 }
384
385 ClusterList &targetClusterList(consolidatedMergeMap[pParentCluster]);
386 targetClusterList.insert(targetClusterList.end(), daughterClusters.begin(), daughterClusters.end());
387 }
388
389 return pAlgorithm->MakeClusterMerges(consolidatedMergeMap);
390}
391
392//------------------------------------------------------------------------------------------------------------------------------------------
393
395{
396 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "NCommonClusters", m_nCommonClusters));
397
398 if ((1 != m_nCommonClusters) && (2 != m_nCommonClusters))
399 {
400 std::cout << "SplitShowersTool: NCommonClusters must be set to either 1 or 2 (provided: " << m_nCommonClusters << ") " << std::endl;
401 return STATUS_CODE_INVALID_PARAMETER;
402 }
403
405 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinMatchedFraction", m_minMatchedFraction));
406
407 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
408 XmlHelper::ReadValue(xmlHandle, "MinMatchedSamplingPoints", m_minMatchedSamplingPoints));
409
410 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
411 XmlHelper::ReadValue(xmlHandle, "CheckClusterProximities", m_checkClusterProximities));
412
414 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxClusterSeparation", m_maxClusterSeparation));
415
416 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
417 XmlHelper::ReadValue(xmlHandle, "CheckClusterVertexRelations", m_checkClusterVertexRelations));
418
419 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
420 XmlHelper::ReadValue(xmlHandle, "MinVertexLongitudinalDistance", m_minVertexLongitudinalDistance));
421
422 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
423 XmlHelper::ReadValue(xmlHandle, "MaxVertexLongitudinalDistance", m_maxVertexLongitudinalDistance));
424
425 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
426 XmlHelper::ReadValue(xmlHandle, "MaxVertexTransverseDistance", m_maxVertexTransverseDistance));
427
429 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "VertexAngularAllowance", m_vertexAngularAllowance));
430
432 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxVertexAssociations", m_maxVertexAssociations));
433
434 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
435 XmlHelper::ReadValue(xmlHandle, "CheckClusterSplitPositions", m_checkClusterSplitPositions));
436
438 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "VetoMergeXDifference", m_vetoMergeXDifference));
439
441 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "VetoMergeXOverlap", m_vetoMergeXOverlap));
442
443 return STATUS_CODE_SUCCESS;
444}
445
446} // namespace lar_content
Grouping of header files for many classes of use in particle flow algorithms.
Header file for the cluster helper class.
Header file for the geometry helper class.
Header file for the lar pointing cluster class.
Header file for the split showers tool class.
#define PANDORA_RETURN_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
Definition StatusCodes.h:31
#define PANDORA_RETURN_RESULT_IF(StatusCode1, Operator, Command)
Definition StatusCodes.h:19
static pandora::StatusCode GetCurrentList(const pandora::Algorithm &algorithm, const T *&pT)
Get the current list.
static const pandora::PandoraSettings * GetSettings(const pandora::Algorithm &algorithm)
Get the pandora settings instance.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
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,...
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.
static pandora::CartesianVector ProjectPosition(const pandora::Pandora &pandora, const pandora::CartesianVector &position3D, const pandora::HitType view)
Project 3D position into a given 2D view.
static bool IsNode(const pandora::CartesianVector &parentVertex, const LArPointingCluster::Vertex &daughterVertex, const float minLongitudinalDistance, const float maxTransverseDistance)
Whether pointing vertex is adjacent to a given position.
static bool IsEmission(const pandora::CartesianVector &parentVertex, const LArPointingCluster::Vertex &daughterVertex, const float minLongitudinalDistance, const float maxLongitudinalDistance, const float maxTransverseDistance, const float angularAllowance)
Whether pointing vertex is emitted from a given position.
LArPointingCluster class.
const Vertex & GetInnerVertex() const
Get the inner vertex.
const Vertex & GetOuterVertex() const
Get the outer vertex.
virtual bool MakeClusterMerges(const ClusterMergeMap &clusterMergeMap)
Merge clusters together.
std::vector< TensorType::ElementList::const_iterator > IteratorList
ThreeViewShowersAlgorithm::MatchingType::TensorType TensorType
float m_vetoMergeXOverlap
The x overlap between candidate cluster sliding fits below which may refuse a merge.
void SelectTensorElements(TensorType::ElementList::const_iterator eIter, const TensorType::ElementList &elementList, const pandora::ClusterSet &usedClusters, IteratorList &iteratorList) const
Select elements representing possible components of interest due to undershoots in clustering.
float m_maxVertexTransverseDistance
Vertex association check: max transverse distance cut.
float m_minVertexLongitudinalDistance
Vertex association check: min longitudinal distance cut.
float m_minMatchedFraction
The min matched sampling point fraction for use as a key tensor element.
void FindShowerMerges(ThreeViewShowersAlgorithm *const pAlgorithm, const IteratorList &iteratorList, pandora::ClusterSet &usedClusters, ClusterMergeMap &clusterMergeMap) const
Get cluster merges specific elements of the tensor.
bool ApplyChanges(ThreeViewShowersAlgorithm *const pAlgorithm, const ClusterMergeMap &clusterMergeMap) const
Apply the changes cached in a cluster merge map and update the tensor accordingly.
float m_vertexAngularAllowance
Vertex association check: pointing angular allowance in degrees.
unsigned int m_minMatchedSamplingPoints
The min number of matched sampling points for use as a key tensor element.
unsigned int m_maxVertexAssociations
The maximum number of vertex associations for clusters to be merged.
bool m_checkClusterSplitPositions
Whether to check the cluster split positions, if there are splits in multiple views.
float m_maxVertexLongitudinalDistance
Vertex association check: max longitudinal distance cut.
bool CheckClusterVertexRelations(ThreeViewShowersAlgorithm *const pAlgorithm, const pandora::ClusterList &clusterList) const
Check the consistency of the clusters in a provided cluster list with the event vertex,...
SplitShowersTool()
Default constructor.
bool m_checkClusterVertexRelations
Whether to check the consistency of the clusters with the event vertex.
bool PassesElementCuts(TensorType::ElementList::const_iterator eIter, const pandora::ClusterSet &usedClusters) const
Whether a provided (iterator to a) tensor element passes the selection cuts for undershoots identific...
float m_vetoMergeXDifference
The x distance between split positions in two views below which may refuse a merge.
bool Run(ThreeViewShowersAlgorithm *const pAlgorithm, TensorType &overlapTensor)
Run the algorithm tool.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
void FindSplitShowers(ThreeViewShowersAlgorithm *const pAlgorithm, const TensorType &overlapTensor, ClusterMergeMap &clusterMergeMap) const
Find split showers, using information from the overlap tensor.
void GetSplitXDetails(ThreeViewShowersAlgorithm *const pAlgorithm, const pandora::Cluster *const pClusterA, const pandora::Cluster *const pClusterB, float &splitXPosition, float &overlapX) const
Get the x coordinate representing the midpoint between two clusters (hypothesis: clusters represent a...
bool CheckClusterSplitPositions(ThreeViewShowersAlgorithm *const pAlgorithm, const pandora::ClusterList &clusterListU, const pandora::ClusterList &clusterListV, const pandora::ClusterList &clusterListW) const
Check the consistency of the split positions in the provided u, v and w cluster lists.
float m_maxClusterSeparation
The maximum separation for clusters to be merged.
bool m_checkClusterProximities
Whether to check the proximities of the candidate split shower clusters.
void SpecifyClusterMerges(ThreeViewShowersAlgorithm *const pAlgorithm, const pandora::ClusterList &clusterList, ClusterMergeMap &clusterMergeMap) const
Populate the cluster merge map, based on the information contained in the provided cluster list.
bool CheckClusterProximities(ThreeViewShowersAlgorithm *const pAlgorithm, const pandora::ClusterList &clusterList) const
Check the clusters in a provided cluster list are in suitable proximity for merging.
unsigned int m_nCommonClusters
The number of common clusters.
const TwoDSlidingShowerFitResult & GetCachedSlidingFitResult(const pandora::Cluster *const pCluster) const
Get a sliding shower fit result from the algorithm cache.
pandora::CartesianVector GetGlobalMinLayerPosition() const
Get global position corresponding to the fit result in minimum fit layer.
pandora::CartesianVector GetGlobalMaxLayerPosition() const
Get global position corresponding to the fit result in maximum fit layer.
const TwoDSlidingFitResult & GetShowerFitResult() const
Get the sliding fit result for the full shower cluster.
CartesianVector class.
float GetX() const
Get the cartesian x coordinate.
Cluster class.
Definition Cluster.h:31
unsigned int GetOuterPseudoLayer() const
Get the outermost pseudo layer in the cluster.
Definition Cluster.h:568
unsigned int GetInnerPseudoLayer() const
Get the innermost pseudo layer in the cluster.
Definition Cluster.h:561
const CartesianVector GetCentroid(const unsigned int pseudoLayer) const
Get unweighted centroid for cluster at a particular pseudo layer, calculated using cached values of h...
Definition Cluster.cc:37
bool ShouldDisplayAlgorithmInfo() const
Whether to display algorithm information during processing.
const std::string & GetType() const
Get the type.
Definition Process.h:102
const Pandora & GetPandora() const
Get the associated pandora instance.
Definition Process.h:116
const std::string & GetInstanceName() const
Get the instance name.
Definition Process.h:109
StatusCodeException class.
Vertex class.
Definition Vertex.h:26
const CartesianVector & GetPosition() const
Get the vertex position.
Definition Vertex.h:103
static StatusCode ReadValue(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, T &t)
Read a value from an xml element.
Definition XmlHelper.h:136
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterMergeMap
HitType
Calorimeter hit type enum.
std::vector< const Cluster * > ClusterVector
MANAGED_CONTAINER< const Cluster * > ClusterList
std::unordered_set< const Cluster * > ClusterSet
std::vector< float > FloatVector
MANAGED_CONTAINER< const Vertex * > VertexList
StatusCode
The StatusCode enum.