Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
CandidateVertexCreationAlgorithm.cc
Go to the documentation of this file.
1
10
13
15
16#include <utility>
17
18using namespace pandora;
19
20namespace lar_content
21{
22
24 m_replaceCurrentVertexList(true),
25 m_slidingFitWindow(20),
26 m_minClusterCaloHits(5),
27 m_minClusterLengthSquared(3.f * 3.f),
28 m_chiSquaredCut(2.f),
29 m_enableEndpointCandidates(true),
30 m_maxEndpointXDiscrepancy(4.f),
31 m_enableCrossingCandidates(false),
32 m_nMaxCrossingCandidates(500),
33 m_maxCrossingXDiscrepancy(0.5f),
34 m_extrapolationNSteps(200),
35 m_extrapolationStepSize(0.1f),
36 m_maxCrossingSeparationSquared(2.f * 2.f),
37 m_minNearbyCrossingDistanceSquared(0.5f * 0.5f),
38 m_reducedCandidates(false),
39 m_selectionCutFactorMax(2.f),
40 m_nClustersPassingMaxCutsPar(26.f)
41{
42}
43
44//------------------------------------------------------------------------------------------------------------------------------------------
45
47{
48 try
49 {
50 ClusterVector clusterVectorU, clusterVectorV, clusterVectorW;
51 this->SelectClusters(clusterVectorU, clusterVectorV, clusterVectorW);
52
53 const VertexList *pVertexList(NULL);
54 std::string temporaryListName;
55 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*this, pVertexList, temporaryListName));
56
58 {
59 this->CreateEndpointCandidates(clusterVectorU, clusterVectorV);
60 this->CreateEndpointCandidates(clusterVectorU, clusterVectorW);
61 this->CreateEndpointCandidates(clusterVectorV, clusterVectorW);
62 }
63
65 this->CreateCrossingCandidates(clusterVectorU, clusterVectorV, clusterVectorW);
66
67 if (!m_inputVertexListName.empty())
68 this->AddInputVertices();
69
70 if (!pVertexList->empty())
71 {
73
76 }
77 }
78 catch (StatusCodeException &statusCodeException)
79 {
80 this->TidyUp();
81 throw statusCodeException;
82 }
83
84 this->TidyUp();
85
86 return STATUS_CODE_SUCCESS;
87}
88
89//------------------------------------------------------------------------------------------------------------------------------------------
90
92{
93 for (const std::string &clusterListName : m_inputClusterListNames)
94 {
95 const ClusterList *pClusterList(NULL);
97 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*this, clusterListName, pClusterList));
98
99 if (!pClusterList || pClusterList->empty())
100 {
102 std::cout << "CandidateVertexCreationAlgorithm: unable to find cluster list " << clusterListName << std::endl;
103
104 continue;
105 }
106
107 const HitType hitType(LArClusterHelper::GetClusterHitType(*(pClusterList->begin())));
108
109 if ((TPC_VIEW_U != hitType) && (TPC_VIEW_V != hitType) && (TPC_VIEW_W != hitType))
110 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
111
112 ClusterVector &selectedClusterVector((TPC_VIEW_U == hitType) ? clusterVectorU : (TPC_VIEW_V == hitType) ? clusterVectorV : clusterVectorW);
113
114 if (!selectedClusterVector.empty())
115 throw StatusCodeException(STATUS_CODE_FAILURE);
116
117 ClusterVector sortedClusters(pClusterList->begin(), pClusterList->end());
118 std::sort(sortedClusters.begin(), sortedClusters.end(), LArClusterHelper::SortByNHits);
119
120 unsigned int nClustersPassingMaxCuts(0);
122 {
123 for (const Cluster *const pCluster : sortedClusters)
124 {
125 float selectionCutFactor(1.f);
126
127 if (pCluster->GetParticleId() == E_MINUS)
128 selectionCutFactor = m_selectionCutFactorMax;
129
130 if (pCluster->GetNCaloHits() < m_minClusterCaloHits * selectionCutFactor)
131 continue;
132
133 if (LArClusterHelper::GetLengthSquared(pCluster) < m_minClusterLengthSquared * selectionCutFactor * selectionCutFactor)
134 continue;
135
136 nClustersPassingMaxCuts++;
137 }
138 }
139
140 for (const Cluster *const pCluster : sortedClusters)
141 {
142 float selectionCutFactor(1.f);
143
144 if (pCluster->GetParticleId() == E_MINUS && m_reducedCandidates)
145 {
146 selectionCutFactor = (m_selectionCutFactorMax + 1.f) * 0.5f +
147 (m_selectionCutFactorMax - 1.f) * 0.5f *
148 std::tanh(static_cast<float>(nClustersPassingMaxCuts) - m_nClustersPassingMaxCutsPar);
149 }
150
151 if (pCluster->GetNCaloHits() < m_minClusterCaloHits * selectionCutFactor)
152 continue;
153
154 if (LArClusterHelper::GetLengthSquared(pCluster) < m_minClusterLengthSquared * selectionCutFactor * selectionCutFactor)
155 continue;
156
157 try
158 {
159 this->AddToSlidingFitCache(pCluster);
160 selectedClusterVector.push_back(pCluster);
161 }
162 catch (StatusCodeException &statusCodeException)
163 {
164 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
165 throw statusCodeException;
166 }
167 }
168 }
169}
170
171//------------------------------------------------------------------------------------------------------------------------------------------
172
173void CandidateVertexCreationAlgorithm::CreateEndpointCandidates(const ClusterVector &clusterVector1, const ClusterVector &clusterVector2) const
174{
175 for (const Cluster *const pCluster1 : clusterVector1)
176 {
177 const HitType hitType1(LArClusterHelper::GetClusterHitType(pCluster1));
178
179 const TwoDSlidingFitResult &fitResult1(this->GetCachedSlidingFitResult(pCluster1));
180 const CartesianVector minLayerPosition1(fitResult1.GetGlobalMinLayerPosition());
181 const CartesianVector maxLayerPosition1(fitResult1.GetGlobalMaxLayerPosition());
182
183 for (const Cluster *const pCluster2 : clusterVector2)
184 {
185 const HitType hitType2(LArClusterHelper::GetClusterHitType(pCluster2));
186
187 const TwoDSlidingFitResult &fitResult2(this->GetCachedSlidingFitResult(pCluster2));
188 const CartesianVector minLayerPosition2(fitResult2.GetGlobalMinLayerPosition());
189 const CartesianVector maxLayerPosition2(fitResult2.GetGlobalMaxLayerPosition());
190
191 this->CreateEndpointVertex(maxLayerPosition1, hitType1, fitResult2);
192 this->CreateEndpointVertex(minLayerPosition1, hitType1, fitResult2);
193 this->CreateEndpointVertex(maxLayerPosition2, hitType2, fitResult1);
194 this->CreateEndpointVertex(minLayerPosition2, hitType2, fitResult1);
195 }
196 }
197}
198
199//------------------------------------------------------------------------------------------------------------------------------------------
200
202 const CartesianVector &position1, const HitType hitType1, const TwoDSlidingFitResult &fitResult2) const
203{
204 const CartesianVector minLayerPosition2(fitResult2.GetGlobalMinLayerPosition());
205 const CartesianVector maxLayerPosition2(fitResult2.GetGlobalMaxLayerPosition());
206
207 if ((((position1.GetX() < minLayerPosition2.GetX()) && (position1.GetX() < maxLayerPosition2.GetX())) ||
208 ((position1.GetX() > minLayerPosition2.GetX()) && (position1.GetX() > maxLayerPosition2.GetX()))) &&
209 (std::fabs(position1.GetX() - minLayerPosition2.GetX()) > m_maxEndpointXDiscrepancy) &&
210 (std::fabs(position1.GetX() - maxLayerPosition2.GetX()) > m_maxEndpointXDiscrepancy))
211 {
212 return;
213 }
214
215 CartesianVector position2(0.f, 0.f, 0.f);
216 if (STATUS_CODE_SUCCESS != fitResult2.GetExtrapolatedPositionAtX(position1.GetX(), position2))
217 return;
218
219 const HitType hitType2(LArClusterHelper::GetClusterHitType(fitResult2.GetCluster()));
220
221 float chiSquared(0.f);
222 CartesianVector position3D(0.f, 0.f, 0.f);
223 LArGeometryHelper::MergeTwoPositions3D(this->GetPandora(), hitType1, hitType2, position1, position2, position3D, chiSquared);
224
225 if (chiSquared > m_chiSquaredCut)
226 return;
227
228 PandoraContentApi::Vertex::Parameters parameters;
229 parameters.m_position = position3D;
230 parameters.m_vertexLabel = VERTEX_INTERACTION;
231 parameters.m_vertexType = VERTEX_3D;
232
233 const Vertex *pVertex(NULL);
234 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*this, parameters, pVertex));
235}
236
237//------------------------------------------------------------------------------------------------------------------------------------------
238
240 const ClusterVector &clusterVectorU, const ClusterVector &clusterVectorV, const ClusterVector &clusterVectorW) const
241{
242 CartesianPointVector crossingsU, crossingsV, crossingsW;
243 this->FindCrossingPoints(clusterVectorU, crossingsU);
244 this->FindCrossingPoints(clusterVectorV, crossingsV);
245 this->FindCrossingPoints(clusterVectorW, crossingsW);
246
247 unsigned int nCrossingCandidates(0);
248 this->CreateCrossingVertices(crossingsU, crossingsV, TPC_VIEW_U, TPC_VIEW_V, nCrossingCandidates);
249 this->CreateCrossingVertices(crossingsU, crossingsW, TPC_VIEW_U, TPC_VIEW_W, nCrossingCandidates);
250 this->CreateCrossingVertices(crossingsV, crossingsW, TPC_VIEW_V, TPC_VIEW_W, nCrossingCandidates);
251}
252
253//------------------------------------------------------------------------------------------------------------------------------------------
254
256{
257 ClusterToSpacepointsMap clusterToSpacepointsMap;
258
259 for (const Cluster *const pCluster : clusterVector)
260 {
261 ClusterToSpacepointsMap::iterator mapIter(clusterToSpacepointsMap.emplace(pCluster, CartesianPointVector()).first);
262 this->GetSpacepoints(pCluster, mapIter->second);
263 }
264
265 for (const Cluster *const pCluster1 : clusterVector)
266 {
267 for (const Cluster *const pCluster2 : clusterVector)
268 {
269 if (pCluster1 == pCluster2)
270 continue;
271
272 this->FindCrossingPoints(clusterToSpacepointsMap.at(pCluster1), clusterToSpacepointsMap.at(pCluster2), crossingPoints);
273 }
274 }
275}
276
277//------------------------------------------------------------------------------------------------------------------------------------------
278
280{
281 LArClusterHelper::GetCoordinateVector(pCluster, spacepoints);
282
283 const TwoDSlidingFitResult &fitResult(this->GetCachedSlidingFitResult(pCluster));
284 const float minLayerRL(fitResult.GetL(fitResult.GetMinLayer()));
285 const float maxLayerRL(fitResult.GetL(fitResult.GetMaxLayer()));
286
287 for (unsigned int iStep = 0; iStep < m_extrapolationNSteps; ++iStep)
288 {
289 const float deltaRL(static_cast<float>(iStep) * m_extrapolationStepSize);
290
291 CartesianVector positionPositive(0.f, 0.f, 0.f), positionNegative(0.f, 0.f, 0.f);
292 fitResult.GetExtrapolatedPosition(maxLayerRL + deltaRL, positionPositive);
293 fitResult.GetExtrapolatedPosition(minLayerRL - deltaRL, positionNegative);
294
295 spacepoints.push_back(positionPositive);
296 spacepoints.push_back(positionNegative);
297 }
298
299 std::sort(spacepoints.begin(), spacepoints.end(), LArClusterHelper::SortCoordinatesByPosition);
300}
301
302//------------------------------------------------------------------------------------------------------------------------------------------
303
305 const CartesianPointVector &spacepoints1, const CartesianPointVector &spacepoints2, CartesianPointVector &crossingPoints) const
306{
307 bool bestCrossingFound(false);
308 float bestSeparationSquared(m_maxCrossingSeparationSquared);
309 CartesianVector bestPosition1(0.f, 0.f, 0.f), bestPosition2(0.f, 0.f, 0.f);
310
311 for (const CartesianVector &position1 : spacepoints1)
312 {
313 for (const CartesianVector &position2 : spacepoints2)
314 {
315 const float separationSquared((position1 - position2).GetMagnitudeSquared());
316
317 if (separationSquared < bestSeparationSquared)
318 {
319 bestCrossingFound = true;
320 bestSeparationSquared = separationSquared;
321 bestPosition1 = position1;
322 bestPosition2 = position2;
323 }
324 }
325 }
326
327 if (bestCrossingFound)
328 {
329 bool alreadyPopulated(false);
330
331 for (const CartesianVector &existingPosition : crossingPoints)
332 {
333 if (((existingPosition - bestPosition1).GetMagnitudeSquared() < m_minNearbyCrossingDistanceSquared) ||
334 ((existingPosition - bestPosition2).GetMagnitudeSquared() < m_minNearbyCrossingDistanceSquared))
335 {
336 alreadyPopulated = true;
337 break;
338 }
339 }
340
341 if (!alreadyPopulated)
342 {
343 crossingPoints.push_back(bestPosition1);
344 crossingPoints.push_back(bestPosition2);
345 }
346 }
347}
348
349//------------------------------------------------------------------------------------------------------------------------------------------
350
352 const CartesianPointVector &crossingPoints2, const HitType hitType1, const HitType hitType2, unsigned int &nCrossingCandidates) const
353{
354
355 for (const CartesianVector &position1 : crossingPoints1)
356 {
357 for (const CartesianVector &position2 : crossingPoints2)
358 {
359 if (nCrossingCandidates > m_nMaxCrossingCandidates)
360 return;
361
362 if (std::fabs(position1.GetX() - position2.GetX()) > m_maxCrossingXDiscrepancy)
363 continue;
364
365 float chiSquared(0.f);
366 CartesianVector position3D(0.f, 0.f, 0.f);
367 LArGeometryHelper::MergeTwoPositions3D(this->GetPandora(), hitType1, hitType2, position1, position2, position3D, chiSquared);
368
369 if (chiSquared > m_chiSquaredCut)
370 continue;
371
372 PandoraContentApi::Vertex::Parameters parameters;
373 parameters.m_position = position3D;
374 parameters.m_vertexLabel = VERTEX_INTERACTION;
375 parameters.m_vertexType = VERTEX_3D;
376
377 const Vertex *pVertex(NULL);
378 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*this, parameters, pVertex));
379 ++nCrossingCandidates;
380 }
381 }
382}
383
384//------------------------------------------------------------------------------------------------------------------------------------------
385
387{
388 const VertexList *pInputVertexList{nullptr};
389 try
390 { // ATTN - No guarantee the list has been initialised, but silent failure here is ok
391 PandoraContentApi::GetList(*this, m_inputVertexListName, pInputVertexList);
392 if (!pInputVertexList)
393 return;
394
395 for (const Vertex *pInputVertex : *pInputVertexList)
396 {
397 PandoraContentApi::Vertex::Parameters parameters;
398 parameters.m_position = pInputVertex->GetPosition();
399 parameters.m_vertexLabel = VERTEX_INTERACTION;
400 parameters.m_vertexType = VERTEX_3D;
401
402 const Vertex *pVertex(nullptr);
403 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*this, parameters, pVertex));
404 }
405 }
406 catch (const StatusCodeException &)
407 {
408 return;
409 }
410}
411
412//------------------------------------------------------------------------------------------------------------------------------------------
413
415{
416 const float slidingFitPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
417 const TwoDSlidingFitResult slidingFitResult(pCluster, m_slidingFitWindow, slidingFitPitch);
418
419 if (!m_slidingFitResultMap.insert(TwoDSlidingFitResultMap::value_type(pCluster, slidingFitResult)).second)
420 throw StatusCodeException(STATUS_CODE_FAILURE);
421}
422
423//------------------------------------------------------------------------------------------------------------------------------------------
424
426{
427 TwoDSlidingFitResultMap::const_iterator iter = m_slidingFitResultMap.find(pCluster);
428
429 if (m_slidingFitResultMap.end() == iter)
430 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
431
432 return iter->second;
433}
434
435//------------------------------------------------------------------------------------------------------------------------------------------
436
441
442//------------------------------------------------------------------------------------------------------------------------------------------
443
445{
446 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadVectorOfValues(xmlHandle, "InputClusterListNames", m_inputClusterListNames));
447
449 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "InputVertexListName", m_inputVertexListName));
450
451 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "OutputVertexListName", m_outputVertexListName));
452
453 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
454 XmlHelper::ReadValue(xmlHandle, "ReplaceCurrentVertexList", m_replaceCurrentVertexList));
455
457 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "SlidingFitWindow", m_slidingFitWindow));
458
460 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinClusterCaloHits", m_minClusterCaloHits));
461
462 float minClusterLength = std::sqrt(m_minClusterLengthSquared);
463 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinClusterLength", minClusterLength));
464 m_minClusterLengthSquared = minClusterLength * minClusterLength;
465
466 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ChiSquaredCut", m_chiSquaredCut));
467
468 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
469 XmlHelper::ReadValue(xmlHandle, "EnableEndpointCandidates", m_enableEndpointCandidates));
470
471 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
472 XmlHelper::ReadValue(xmlHandle, "MaxEndpointXDiscrepancy", m_maxEndpointXDiscrepancy));
473
474 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
475 XmlHelper::ReadValue(xmlHandle, "EnableCrossingCandidates", m_enableCrossingCandidates));
476
478 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "NMaxCrossingCandidates", m_nMaxCrossingCandidates));
479
480 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
481 XmlHelper::ReadValue(xmlHandle, "MaxCrossingXDiscrepancy", m_maxCrossingXDiscrepancy));
482
484 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ExtrapolationNSteps", m_extrapolationNSteps));
485
487 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ExtrapolationStepSize", m_extrapolationStepSize));
488
490 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ReducedCandidates", m_reducedCandidates));
491
493 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "SelectionCutFactorMax", m_selectionCutFactorMax));
494
495 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
496 XmlHelper::ReadValue(xmlHandle, "NClustersPassingMaxCutsPar", m_nClustersPassingMaxCutsPar));
497
498 float maxCrossingSeparation = std::sqrt(m_maxCrossingSeparationSquared);
500 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxCrossingSeparation", maxCrossingSeparation));
501 m_maxCrossingSeparationSquared = maxCrossingSeparation * maxCrossingSeparation;
502
503 float minNearbyCrossingDistance = std::sqrt(m_minNearbyCrossingDistanceSquared);
504 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
505 XmlHelper::ReadValue(xmlHandle, "MinNearbyCrossingDistance", minNearbyCrossingDistance));
506 m_minNearbyCrossingDistanceSquared = minNearbyCrossingDistance * minNearbyCrossingDistance;
507
508 return STATUS_CODE_SUCCESS;
509}
510
511} // namespace lar_content
Grouping of header files for many classes of use in particle flow algorithms.
Header file for the candidate vertex creation algorithm class.
Header file for the cluster helper class.
Header file for the geometry helper class.
#define PANDORA_THROW_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
Definition StatusCodes.h:55
#define PANDORA_THROW_RESULT_IF(StatusCode1, Operator, Command)
Definition StatusCodes.h:43
#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 ReplaceCurrentList(const pandora::Algorithm &algorithm, const std::string &newListName)
Replace the current list with a pre-saved list; use this new list as a permanent replacement for the ...
static pandora::StatusCode CreateTemporaryListAndSetCurrent(const pandora::Algorithm &algorithm, const T *&pT, std::string &temporaryListName)
Create a temporary list and set it to be the current list, enabling object creation.
static pandora::StatusCode GetList(const pandora::Algorithm &algorithm, const std::string &listName, const T *&pT)
Get a named list.
static const pandora::PandoraSettings * GetSettings(const pandora::Algorithm &algorithm)
Get the pandora settings instance.
void CreateEndpointVertex(const pandora::CartesianVector &position1, const pandora::HitType hitType1, const TwoDSlidingFitResult &fitResult2) const
Create a candidate vertex position, using an end-point position from one cluster and sliding fit to a...
float m_selectionCutFactorMax
Maximum factor to multiply the base cluster selection cuts.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
void AddInputVertices() const
Add candidate vertices from any input vertices.
const TwoDSlidingFitResult & GetCachedSlidingFitResult(const pandora::Cluster *const pCluster) const
Get a sliding fit result from the algorithm cache.
unsigned int m_extrapolationNSteps
Number of extrapolation steps, at each end of cluster, of specified size.
void FindCrossingPoints(const pandora::ClusterVector &clusterVector, pandora::CartesianPointVector &crossingPoints) const
Identify where (extrapolated) clusters plausibly cross in 2D.
bool m_enableEndpointCandidates
Whether to create endpoint-based candidates.
float m_maxCrossingXDiscrepancy
The max cluster endpoint discrepancy.
bool m_enableCrossingCandidates
Whether to create crossing vertex candidates.
float m_maxCrossingSeparationSquared
The separation (squared) between spacepoints below which a crossing can be identified.
void GetSpacepoints(const pandora::Cluster *const pCluster, pandora::CartesianPointVector &spacePoints) const
Get a list of spacepoints representing cluster 2D hit positions and extrapolated positions.
void SelectClusters(pandora::ClusterVector &clusterVectorU, pandora::ClusterVector &clusterVectorV, pandora::ClusterVector &clusterVectorW)
Select a subset of input clusters (contained in the input list names) for processing in this algorith...
void CreateEndpointCandidates(const pandora::ClusterVector &clusterVector1, const pandora::ClusterVector &clusterVector2) const
Create candidate vertex positions by comparing pairs of cluster end positions.
TwoDSlidingFitResultMap m_slidingFitResultMap
The sliding fit result map.
float m_nClustersPassingMaxCutsPar
Parameter for number of clusters passing the max base cluster selection cuts.
std::unordered_map< const pandora::Cluster *, pandora::CartesianPointVector > ClusterToSpacepointsMap
void CreateCrossingCandidates(const pandora::ClusterVector &clusterVectorU, const pandora::ClusterVector &clusterVectorV, const pandora::ClusterVector &clusterVectorW) const
Extrapolate 2D clusters, find where they cross, and match crossing points between views to create ver...
void CreateCrossingVertices(const pandora::CartesianPointVector &crossingPoints1, const pandora::CartesianPointVector &crossingPoints2, const pandora::HitType hitType1, const pandora::HitType hitType2, unsigned int &nCrossingCandidates) const
Attempt to create candidate vertex positions, using 2D crossing points in 2 views.
void TidyUp()
Clear relevant algorithm member variables between events.
float m_maxEndpointXDiscrepancy
The max cluster endpoint discrepancy.
std::string m_outputVertexListName
The name under which to save the output vertex list.
bool m_replaceCurrentVertexList
Whether to replace the current vertex list with the output list.
unsigned int m_slidingFitWindow
The layer window for the sliding linear fits.
unsigned int m_nMaxCrossingCandidates
The max number of crossing candidates to create.
float m_minClusterLengthSquared
The min length (squared) in base cluster selection method.
std::string m_inputVertexListName
The list name for existing candidate vertices.
bool m_reducedCandidates
Whether to reduce the number of candidates.
pandora::StringVector m_inputClusterListNames
The list of cluster list names.
float m_minNearbyCrossingDistanceSquared
The minimum allowed distance between identified crossing positions.
unsigned int m_minClusterCaloHits
The min number of hits in base cluster selection method.
void AddToSlidingFitCache(const pandora::Cluster *const pCluster)
Creates a 2D sliding fit of a cluster and stores it for later use.
float m_chiSquaredCut
The chi squared cut (accept only 3D vertex positions with values below cut)
float m_extrapolationStepSize
The extrapolation step size in cm.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
static void GetCoordinateVector(const pandora::Cluster *const pCluster, pandora::CartesianPointVector &coordinateVector)
Get vector of hit coordinates from an input cluster.
static bool SortCoordinatesByPosition(const pandora::CartesianVector &lhs, const pandora::CartesianVector &rhs)
Sort cartesian vectors by their position (use Z, followed by X, followed by Y)
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 GetLengthSquared(const pandora::Cluster *const pCluster)
Get length squared of cluster.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
static void MergeTwoPositions3D(const pandora::Pandora &pandora, const pandora::HitType view1, const pandora::HitType view2, const pandora::CartesianVector &position1, const pandora::CartesianVector &position2, pandora::CartesianVector &position3D, float &chiSquared)
Merge 2D positions from two views to give unified 3D position.
float GetL(const int layer) const
Get longitudinal coordinate for a given sliding linear fit layer number.
pandora::CartesianVector GetGlobalMinLayerPosition() const
Get global position corresponding to the fit result in minimum fit layer.
int GetMaxLayer() const
Get the maximum occupied layer in the sliding fit.
pandora::StatusCode GetExtrapolatedPositionAtX(const float x, pandora::CartesianVector &position) const
Get extrapolated position (beyond span) for a given input x coordinate.
pandora::CartesianVector GetGlobalMaxLayerPosition() const
Get global position corresponding to the fit result in maximum fit layer.
pandora::StatusCode GetExtrapolatedPosition(const float rL, pandora::CartesianVector &position) const
Get extrapolated position (beyond span) for a given input coordinate.
const pandora::Cluster * GetCluster() const
Get the address of the cluster, if originally provided.
int GetMinLayer() const
Get the minimum occupied layer in the sliding fit.
CartesianVector class.
float GetX() const
Get the cartesian x coordinate.
Cluster class.
Definition Cluster.h:31
bool ShouldDisplayAlgorithmInfo() const
Whether to display algorithm information during processing.
const Pandora & GetPandora() const
Get the associated pandora instance.
Definition Process.h:116
StatusCodeException class.
StatusCode GetStatusCode() const
Get status code.
Vertex class.
Definition Vertex.h:26
static StatusCode ReadVectorOfValues(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, std::vector< T > &vector)
Read a vector of values from a (space separated) list in an xml element.
Definition XmlHelper.h:229
static StatusCode ReadValue(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, T &t)
Read a value from an xml element.
Definition XmlHelper.h:136
HitType
Calorimeter hit type enum.
std::vector< const Cluster * > ClusterVector
MANAGED_CONTAINER< const Cluster * > ClusterList
std::vector< CartesianVector > CartesianPointVector
MANAGED_CONTAINER< const Vertex * > VertexList
StatusCode
The StatusCode enum.