Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
NViewDeltaRayMatchingAlgorithm.cc
Go to the documentation of this file.
1
10
15
19
21
24
26
27using namespace pandora;
28
29namespace lar_content
30{
31
32template <typename T>
34 m_pseudoChi2Cut(1.5f),
35 m_xOverlapWindow(1.f),
36 m_minMatchedFraction(0.5),
37 m_minMatchedPoints(3),
38 m_minProjectedPositions(3),
39 m_maxCosmicRayHitFraction(0.05f),
40 m_maxDistanceToCluster(0.5f),
41 m_maxDistanceToReferencePoint(5.f),
42 m_strayClusterSeparation(2.f)
43{
44}
45
46//------------------------------------------------------------------------------------------------------------------------------------------
47
48template <typename T>
49void NViewDeltaRayMatchingAlgorithm<T>::SelectInputClusters(const ClusterList *const pInputClusterList, ClusterList &selectedClusterList) const
51 for (const Cluster *const pCluster : *pInputClusterList)
52 {
53 if ((pCluster->IsAvailable()) && (this->DoesClusterPassTensorThreshold(pCluster)))
54 selectedClusterList.push_back(pCluster);
55 }
56}
57
58//------------------------------------------------------------------------------------------------------------------------------------------
59
60template <typename T>
62{
63 if (preparedClusterList.empty())
64 return;
65
66 const PfoList *pMuonPfoList(nullptr);
67
69 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*this, m_muonPfoListName, pMuonPfoList));
70
71 if ((!pMuonPfoList) || pMuonPfoList->empty())
72 return;
73
74 const HitType hitType(LArClusterHelper::GetClusterHitType(preparedClusterList.front()));
75
76 m_deltaRayMatchingContainers.FillContainers(*pMuonPfoList, this->GetInputClusterList(hitType));
77
78 this->FillStrayClusterList(LArClusterHelper::GetClusterHitType(preparedClusterList.front()));
80
81//------------------------------------------------------------------------------------------------------------------------------------------
82
83template <typename T>
85{
86 const ClusterList &inputClusterList(this->GetInputClusterList(hitType));
87 ClusterList &strayClusterList((hitType == TPC_VIEW_U) ? m_strayClusterListU : (hitType == TPC_VIEW_V) ? m_strayClusterListV : m_strayClusterListW);
88
89 for (const Cluster *const pCluster : inputClusterList)
90 {
91 if ((pCluster->IsAvailable()) && (!this->DoesClusterPassTensorThreshold(pCluster)))
92 strayClusterList.push_back(pCluster);
93 }
94}
95
96//------------------------------------------------------------------------------------------------------------------------------------------
97
98template <typename T>
99StatusCode NViewDeltaRayMatchingAlgorithm<T>::GetMuonCluster(const PfoList &commonMuonPfoList, const HitType hitType, const Cluster *&pMuonCluster) const
100{
101 if (commonMuonPfoList.size() != 1)
102 return STATUS_CODE_NOT_FOUND;
103
104 ClusterList muonClusterList;
105 LArPfoHelper::GetClusters(commonMuonPfoList.front(), hitType, muonClusterList);
106
107 if (muonClusterList.size() != 1)
108 return STATUS_CODE_NOT_FOUND;
110 pMuonCluster = muonClusterList.front();
111
112 return STATUS_CODE_SUCCESS;
113}
114
115//------------------------------------------------------------------------------------------------------------------------------------------
116
117template <typename T>
118void NViewDeltaRayMatchingAlgorithm<T>::GetNearbyMuonPfos(const Cluster *const pCluster, ClusterList &consideredClusters, PfoList &nearbyMuonPfos) const
119{
120 const HitType hitType(LArClusterHelper::GetClusterHitType(pCluster));
121 const DeltaRayMatchingContainers::ClusterToPfoMap &clusterToPfoMap(m_deltaRayMatchingContainers.GetClusterToPfoMap(hitType));
122 const DeltaRayMatchingContainers::ClusterProximityMap &clusterProximityMap(m_deltaRayMatchingContainers.GetClusterProximityMap(hitType));
123
124 consideredClusters.push_back(pCluster);
125
126 const DeltaRayMatchingContainers::ClusterProximityMap::const_iterator clusterProximityIter(clusterProximityMap.find(pCluster));
127
128 if (clusterProximityIter == clusterProximityMap.end())
129 return;
130
131 for (const Cluster *const pNearbyCluster : clusterProximityIter->second)
132 {
133 if (std::find(consideredClusters.begin(), consideredClusters.end(), pNearbyCluster) != consideredClusters.end())
134 continue;
135
136 const DeltaRayMatchingContainers::ClusterToPfoMap::const_iterator pfoIter(clusterToPfoMap.find(pNearbyCluster));
137
138 if (pfoIter != clusterToPfoMap.end())
139 {
140 if (std::find(nearbyMuonPfos.begin(), nearbyMuonPfos.end(), pfoIter->second) == nearbyMuonPfos.end())
141 nearbyMuonPfos.push_back(pfoIter->second);
142
143 continue;
144 }
145
146 this->GetNearbyMuonPfos(pNearbyCluster, consideredClusters, nearbyMuonPfos);
147 }
148}
149
150//------------------------------------------------------------------------------------------------------------------------------------------
151
152template <typename T>
154 const Cluster *const pCluster1, const Cluster *const pCluster2, const Cluster *const pCluster3, float &reducedChiSquared) const
155{
156 float chiSquaredSum(0.f);
157 unsigned int nSamplingPoints(0), nMatchedSamplingPoints(0);
158 XOverlap xThreeViewOverlapObject(0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f);
159
160 if (this->PerformThreeViewMatching(pCluster1, pCluster2, pCluster3, chiSquaredSum, nSamplingPoints, nMatchedSamplingPoints,
161 xThreeViewOverlapObject) == STATUS_CODE_NOT_FOUND)
162 return STATUS_CODE_NOT_FOUND;
163
164 if (nSamplingPoints == 0)
165 return STATUS_CODE_NOT_FOUND;
166
167 reducedChiSquared = chiSquaredSum / nSamplingPoints;
168
169 return STATUS_CODE_SUCCESS;
170}
171
172//------------------------------------------------------------------------------------------------------------------------------------------
173
174template <typename T>
176 const Cluster *const pClusterW, float &chiSquaredSum, unsigned int &nSamplingPoints, unsigned int &nMatchedSamplingPoints, XOverlap &xOverlapObject) const
177{
178 float xMinU(-std::numeric_limits<float>::max()), xMaxU(+std::numeric_limits<float>::max());
179 float xMinV(-std::numeric_limits<float>::max()), xMaxV(+std::numeric_limits<float>::max());
180 float xMinW(-std::numeric_limits<float>::max()), xMaxW(+std::numeric_limits<float>::max());
181
182 pClusterU->GetClusterSpanX(xMinU, xMaxU);
183 pClusterV->GetClusterSpanX(xMinV, xMaxV);
184 pClusterW->GetClusterSpanX(xMinW, xMaxW);
185
186 // Need to remove the xPitch from calculations to be consistent with view xSpan calculated in the xOverlapObject
187 const float xMinCentre(std::max(xMinU, std::max(xMinV, xMinW)));
188 const float xMaxCentre(std::min(xMaxU, std::min(xMaxV, xMaxW)));
189 const float xCentreOverlap(xMaxCentre - xMinCentre);
190
191 if (xCentreOverlap < std::numeric_limits<float>::epsilon())
192 return STATUS_CODE_NOT_FOUND;
194 const float xPitch(0.5 * m_xOverlapWindow);
195 const float xMin(std::max(xMinU, std::max(xMinV, xMinW)) - xPitch);
196 const float xMax(std::min(xMaxU, std::min(xMaxV, xMaxW)) + xPitch);
197 const float xOverlap(xMax - xMin);
198
199 const HitType hitTypeU(LArClusterHelper::GetClusterHitType(pClusterU));
200 const HitType hitTypeV(LArClusterHelper::GetClusterHitType(pClusterV));
201 const HitType hitTypeW(LArClusterHelper::GetClusterHitType(pClusterW));
202
203 if (hitTypeU == hitTypeV || hitTypeU == hitTypeW || hitTypeV == hitTypeW)
204 return STATUS_CODE_FAILURE;
205
206 const unsigned int nPoints(1 + static_cast<unsigned int>(xOverlap / xPitch));
207
208 chiSquaredSum = 0.f;
209 nSamplingPoints = 0;
210 nMatchedSamplingPoints = 0;
211
212 for (unsigned int n = 0; n < nPoints; ++n)
213 {
214 const float x(xMin + (xMax - xMin) * (static_cast<float>(n) + 0.5f) / static_cast<float>(nPoints));
215 const float xmin(x - xPitch);
216 const float xmax(x + xPitch);
217
218 try
219 {
220 float zMinU(0.f), zMinV(0.f), zMinW(0.f), zMaxU(0.f), zMaxV(0.f), zMaxW(0.f);
221 pClusterU->GetClusterSpanZ(xmin, xmax, zMinU, zMaxU);
222 pClusterV->GetClusterSpanZ(xmin, xmax, zMinV, zMaxV);
223 pClusterW->GetClusterSpanZ(xmin, xmax, zMinW, zMaxW);
225 const float zU(0.5f * (zMinU + zMaxU));
226 const float zV(0.5f * (zMinV + zMaxV));
227 const float zW(0.5f * (zMinW + zMaxW));
228
229 const float dzU(zMaxU - zMinU);
230 const float dzV(zMaxV - zMinV);
231 const float dzW(zMaxW - zMinW);
232 const float dzPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
233
234 const float zprojU(LArGeometryHelper::MergeTwoPositions(this->GetPandora(), hitTypeV, hitTypeW, zV, zW));
235 const float zprojV(LArGeometryHelper::MergeTwoPositions(this->GetPandora(), hitTypeW, hitTypeU, zW, zU));
236 const float zprojW(LArGeometryHelper::MergeTwoPositions(this->GetPandora(), hitTypeU, hitTypeV, zU, zV));
237
238 ++nSamplingPoints;
239
240 const float deltaSquared(((zU - zprojU) * (zU - zprojU) + (zV - zprojV) * (zV - zprojV) + (zW - zprojW) * (zW - zprojW)) / 3.f);
241 const float sigmaSquared(dzU * dzU + dzV * dzV + dzW * dzW + dzPitch * dzPitch);
242 const float pseudoChi2(deltaSquared / sigmaSquared);
244 chiSquaredSum += pseudoChi2;
245
246 if (pseudoChi2 < m_pseudoChi2Cut)
247 ++nMatchedSamplingPoints;
248 }
249 catch (StatusCodeException &statusCodeException)
250 {
251 if (statusCodeException.GetStatusCode() != STATUS_CODE_NOT_FOUND)
252 return statusCodeException.GetStatusCode();
253
254 continue;
255 }
256 }
257
258 // Apply tensor threshold cuts
259 if (nSamplingPoints == 0)
260 return STATUS_CODE_NOT_FOUND;
262 const float matchedFraction(static_cast<float>(nMatchedSamplingPoints) / static_cast<float>(nSamplingPoints));
263
264 if ((matchedFraction < m_minMatchedFraction) || (nMatchedSamplingPoints < m_minMatchedPoints))
265 return STATUS_CODE_NOT_FOUND;
266
267 xOverlapObject = XOverlap(xMinU, xMaxU, xMinV, xMaxV, xMinW, xMaxW, xCentreOverlap);
268
269 return STATUS_CODE_SUCCESS;
270}
271
272//------------------------------------------------------------------------------------------------------------------------------------------
273
274template <typename T>
276 const CaloHitList &pCluster1, const CaloHitList &pCluster2, const CaloHitList &pCluster3, float &reducedChiSquared) const
277{
278 float chiSquaredSum(0.f);
279 unsigned int nSamplingPoints(0), nMatchedSamplingPoints(0);
280 XOverlap xThreeViewOverlapObject(0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f);
281
282 if (this->PerformThreeViewMatching(pCluster1, pCluster2, pCluster3, chiSquaredSum, nSamplingPoints, nMatchedSamplingPoints,
283 xThreeViewOverlapObject) == STATUS_CODE_NOT_FOUND)
284 return STATUS_CODE_NOT_FOUND;
285
286 if (nSamplingPoints == 0)
287 return STATUS_CODE_NOT_FOUND;
288
289 reducedChiSquared = chiSquaredSum / nSamplingPoints;
290
291 return STATUS_CODE_SUCCESS;
292}
294//------------------------------------------------------------------------------------------------------------------------------------------
295
296template <typename T>
298 const CaloHitList &clusterW, float &chiSquaredSum, unsigned int &nSamplingPoints, unsigned int &nMatchedSamplingPoints, XOverlap &xOverlapObject) const
299{
300 float xMinU(-std::numeric_limits<float>::max()), xMaxU(+std::numeric_limits<float>::max());
301 float xMinV(-std::numeric_limits<float>::max()), xMaxV(+std::numeric_limits<float>::max());
302 float xMinW(-std::numeric_limits<float>::max()), xMaxW(+std::numeric_limits<float>::max());
303
304 this->GetClusterSpanX(clusterU, xMinU, xMaxU);
305 this->GetClusterSpanX(clusterV, xMinV, xMaxV);
306 this->GetClusterSpanX(clusterW, xMinW, xMaxW);
307
308 // Need to remove the xPitch from calculations to be consistent with view xSpan calculated in the xOverlapObject
309 const float xMinCentre(std::max(xMinU, std::max(xMinV, xMinW)));
310 const float xMaxCentre(std::min(xMaxU, std::min(xMaxV, xMaxW)));
311 const float xCentreOverlap(xMaxCentre - xMinCentre);
312
313 if (xCentreOverlap < std::numeric_limits<float>::epsilon())
314 return STATUS_CODE_NOT_FOUND;
315
316 const float xPitch(0.5 * m_xOverlapWindow);
317 const float xMin(std::max(xMinU, std::max(xMinV, xMinW)) - xPitch);
318 const float xMax(std::min(xMaxU, std::min(xMaxV, xMaxW)) + xPitch);
319 const float xOverlap(xMax - xMin);
320
321 const HitType hitTypeU(clusterU.front()->GetHitType());
322 const HitType hitTypeV(clusterV.front()->GetHitType());
323 const HitType hitTypeW(clusterW.front()->GetHitType());
324
325 if (hitTypeU == hitTypeV || hitTypeU == hitTypeW || hitTypeV == hitTypeW)
326 return STATUS_CODE_FAILURE;
327
328 const unsigned int nPoints(1 + static_cast<unsigned int>(xOverlap / xPitch));
329
330 chiSquaredSum = 0.f;
331 nSamplingPoints = 0;
332 nMatchedSamplingPoints = 0;
333
334 for (unsigned int n = 0; n < nPoints; ++n)
335 {
336 const float x(xMin + (xMax - xMin) * (static_cast<float>(n) + 0.5f) / static_cast<float>(nPoints));
337 const float xmin(x - xPitch);
338 const float xmax(x + xPitch);
339
340 try
341 {
342 float zMinU(0.f), zMinV(0.f), zMinW(0.f), zMaxU(0.f), zMaxV(0.f), zMaxW(0.f);
343 this->GetClusterSpanZ(clusterU, xmin, xmax, zMinU, zMaxU);
344 this->GetClusterSpanZ(clusterV, xmin, xmax, zMinV, zMaxV);
345 this->GetClusterSpanZ(clusterW, xmin, xmax, zMinW, zMaxW);
346
347 const float zU(0.5f * (zMinU + zMaxU));
348 const float zV(0.5f * (zMinV + zMaxV));
349 const float zW(0.5f * (zMinW + zMaxW));
350
351 const float dzU(zMaxU - zMinU);
352 const float dzV(zMaxV - zMinV);
353 const float dzW(zMaxW - zMinW);
354 const float dzPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
355
356 const float zprojU(LArGeometryHelper::MergeTwoPositions(this->GetPandora(), hitTypeV, hitTypeW, zV, zW));
357 const float zprojV(LArGeometryHelper::MergeTwoPositions(this->GetPandora(), hitTypeW, hitTypeU, zW, zU));
358 const float zprojW(LArGeometryHelper::MergeTwoPositions(this->GetPandora(), hitTypeU, hitTypeV, zU, zV));
359
360 ++nSamplingPoints;
361
362 const float deltaSquared(((zU - zprojU) * (zU - zprojU) + (zV - zprojV) * (zV - zprojV) + (zW - zprojW) * (zW - zprojW)) / 3.f);
363 const float sigmaSquared(dzU * dzU + dzV * dzV + dzW * dzW + dzPitch * dzPitch);
364 const float pseudoChi2(deltaSquared / sigmaSquared);
365
366 chiSquaredSum += pseudoChi2;
367
368 if (pseudoChi2 < m_pseudoChi2Cut)
369 ++nMatchedSamplingPoints;
370 }
371 catch (StatusCodeException &statusCodeException)
372 {
373 if (statusCodeException.GetStatusCode() != STATUS_CODE_NOT_FOUND)
374 return statusCodeException.GetStatusCode();
375
376 continue;
377 }
378 }
379
380 // Apply tensor threshold cuts
381 if (nSamplingPoints == 0)
382 return STATUS_CODE_NOT_FOUND;
383
384 const float matchedFraction(static_cast<float>(nMatchedSamplingPoints) / static_cast<float>(nSamplingPoints));
385
386 if ((matchedFraction < m_minMatchedFraction) || (nMatchedSamplingPoints < m_minMatchedPoints))
387 return STATUS_CODE_NOT_FOUND;
388
389 xOverlapObject = XOverlap(xMinU, xMaxU, xMinV, xMaxV, xMinW, xMaxW, xCentreOverlap);
390
391 return STATUS_CODE_SUCCESS;
392}
393
394//------------------------------------------------------------------------------------------------------------------------------------------
395
396template <typename T>
397void NViewDeltaRayMatchingAlgorithm<T>::GetClusterSpanX(const CaloHitList &caloHitList, float &xMin, float &xMax) const
398{
399 xMin = std::numeric_limits<float>::max();
400 xMax = -std::numeric_limits<float>::max();
401
402 for (const CaloHit *const pCaloHit : caloHitList)
403 {
404 const float xCoordinate(pCaloHit->GetPositionVector().GetX());
405
406 if (xCoordinate < xMin)
407 xMin = xCoordinate;
408
409 if (xCoordinate > xMax)
410 xMax = xCoordinate;
411 }
412}
413
414//------------------------------------------------------------------------------------------------------------------------------------------
415
416template <typename T>
418 const CaloHitList &caloHitList, const float xMin, const float xMax, float &zMin, float &zMax) const
419{
420 zMin = std::numeric_limits<float>::max();
421 zMax = -std::numeric_limits<float>::max();
422
423 bool found(false);
424 for (const CaloHit *const pCaloHit : caloHitList)
425 {
426 const float xCoordinate(pCaloHit->GetPositionVector().GetX());
427 const float zCoordinate(pCaloHit->GetPositionVector().GetZ());
428
429 if ((xCoordinate < xMin) || (xCoordinate > xMax))
430 continue;
431
432 found = true;
433
434 if (zCoordinate < zMin)
435 zMin = zCoordinate;
436
437 if (zCoordinate > zMax)
438 zMax = zCoordinate;
439 }
440
441 if (!found)
442 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
443
444 return STATUS_CODE_SUCCESS;
445}
446
447//------------------------------------------------------------------------------------------------------------------------------------------
448
449template <typename T>
451 const HitType &thirdViewHitType, const ParticleFlowObject *const pParentMuon, CartesianPointVector &projectedPositions) const
452{
453 ClusterList muonClusterList1, muonClusterList2;
454
456
457 hitTypes.erase(std::find(hitTypes.begin(), hitTypes.end(), thirdViewHitType));
458
459 LArPfoHelper::GetClusters(pParentMuon, hitTypes[0], muonClusterList1);
460 LArPfoHelper::GetClusters(pParentMuon, hitTypes[1], muonClusterList2);
461
462 if ((muonClusterList1.size() != 1) || (muonClusterList2.size() != 1))
463 return STATUS_CODE_NOT_FOUND;
464
465 return (this->GetProjectedPositions(muonClusterList1.front(), muonClusterList2.front(), projectedPositions));
466}
467
468//------------------------------------------------------------------------------------------------------------------------------------------
469
470template <typename T>
472 const Cluster *const pCluster1, const Cluster *const pCluster2, CartesianPointVector &projectedPositions) const
473{
474 float xMin1(0.f), xMax1(0.f), xMin2(0.f), xMax2(0.f);
475 pCluster1->GetClusterSpanX(xMin1, xMax1);
476 pCluster2->GetClusterSpanX(xMin2, xMax2);
477
478 const float xPitch(0.5 * m_xOverlapWindow);
479 const float xMin(std::max(xMin1, xMin2) - xPitch);
480 const float xMax(std::min(xMax1, xMax2) + xPitch);
481 const float xOverlap(xMax - xMin);
482
483 if (xOverlap < std::numeric_limits<float>::epsilon())
484 return STATUS_CODE_NOT_FOUND;
485
486 const HitType hitType1(LArClusterHelper::GetClusterHitType(pCluster1));
487 const HitType hitType2(LArClusterHelper::GetClusterHitType(pCluster2));
488
489 if (hitType1 == hitType2)
490 throw StatusCodeException(STATUS_CODE_FAILURE);
491
492 const unsigned int nPoints(1 + static_cast<unsigned int>(xOverlap / xPitch));
493
494 // Projection into third view
495 for (unsigned int n = 0; n < nPoints; ++n)
496 {
497 const float x(xMin + (xMax - xMin) * (static_cast<float>(n) + 0.5f) / static_cast<float>(nPoints));
498 const float xmin(x - xPitch);
499 const float xmax(x + xPitch);
500
501 try
502 {
503 float zMin1(0.f), zMin2(0.f), zMax1(0.f), zMax2(0.f);
504 pCluster1->GetClusterSpanZ(xmin, xmax, zMin1, zMax1);
505 pCluster2->GetClusterSpanZ(xmin, xmax, zMin2, zMax2);
506
507 const float z1(0.5f * (zMin1 + zMax1));
508 const float z2(0.5f * (zMin2 + zMax2));
509
510 float chi2;
511 CartesianVector projection(0.f, 0.f, 0.f);
513 this->GetPandora(), hitType1, hitType2, CartesianVector(x, 0.f, z1), CartesianVector(x, 0.f, z2), projection, chi2);
514
515 projectedPositions.push_back(projection);
516 }
517 catch (StatusCodeException &statusCodeException)
518 {
519 if (statusCodeException.GetStatusCode() != STATUS_CODE_NOT_FOUND)
520 throw statusCodeException.GetStatusCode();
521
522 continue;
523 }
524 }
525
526 // Reject if projection is not good
527 if (projectedPositions.size() < m_minProjectedPositions)
528 return STATUS_CODE_NOT_FOUND;
529
530 return STATUS_CODE_SUCCESS;
531}
532
533//------------------------------------------------------------------------------------------------------------------------------------------
534
535template <typename T>
537 const Cluster *const pThirdViewCluster, const ParticleFlowObject *const pParentMuon, const float minDistanceFromMuon,
538 const float maxDistanceToCollected, CaloHitList &collectedHits) const
539{
540 HitType thirdViewHitType(TPC_VIEW_U);
541 CartesianPointVector deltaRayProjectedPositions;
542
543 if (!pThirdViewCluster)
544 {
545 if (this->GetProjectedPositions(pCluster1, pCluster2, deltaRayProjectedPositions) != STATUS_CODE_SUCCESS)
546 return STATUS_CODE_NOT_FOUND;
547
548 for (const HitType hitType : {TPC_VIEW_U, TPC_VIEW_V, TPC_VIEW_W})
549 {
550 if ((LArClusterHelper::GetClusterHitType(pCluster1) != hitType) && (LArClusterHelper::GetClusterHitType(pCluster2) != hitType))
551 {
552 thirdViewHitType = hitType;
553 break;
554 }
555 }
556 }
557 else
558 {
559 CaloHitList deltaRayCaloHitList;
560 pThirdViewCluster->GetOrderedCaloHitList().FillCaloHitList(deltaRayCaloHitList);
561
562 for (const CaloHit *const pCaloHit : deltaRayCaloHitList)
563 deltaRayProjectedPositions.push_back(pCaloHit->GetPositionVector());
564
565 thirdViewHitType = LArClusterHelper::GetClusterHitType(pThirdViewCluster);
566 }
567
568 ClusterList muonClusterList;
569 LArPfoHelper::GetClusters(pParentMuon, thirdViewHitType, muonClusterList);
570
571 if (muonClusterList.size() != 1)
572 return STATUS_CODE_NOT_FOUND;
573
574 const Cluster *const pMuonCluster(muonClusterList.front());
575
576 // To avoid fluctuatuions, parameterise the muon track
577 CartesianVector positionOnMuon(0.f, 0.f, 0.f), muonDirection(0.f, 0.f, 0.f);
578 if (this->ParameteriseMuon(pParentMuon, deltaRayProjectedPositions, thirdViewHitType, positionOnMuon, muonDirection) != STATUS_CODE_SUCCESS)
579 return STATUS_CODE_NOT_FOUND;
580
581 this->CollectHitsFromMuon(
582 positionOnMuon, muonDirection, pMuonCluster, deltaRayProjectedPositions, minDistanceFromMuon, maxDistanceToCollected, collectedHits);
583
584 if (collectedHits.empty())
585 return STATUS_CODE_NOT_FOUND;
586
587 // Catch if delta ray has travelled along muon
588 if ((static_cast<float>(collectedHits.size()) / pMuonCluster->GetNCaloHits()) > m_maxCosmicRayHitFraction)
589 return STATUS_CODE_NOT_FOUND;
590
591 return STATUS_CODE_SUCCESS;
592}
593
594//------------------------------------------------------------------------------------------------------------------------------------------
595
596template <typename T>
598 const Cluster *const pMuonCluster, const CartesianPointVector &deltaRayProjectedPositions, const float &minDistanceFromMuon,
599 const float maxDistanceToCollected, CaloHitList &collectedHits) const
600{
601 CaloHitList cosmicRayHitList;
602 pMuonCluster->GetOrderedCaloHitList().FillCaloHitList(cosmicRayHitList);
603
604 bool hitsAdded(true);
605 while (hitsAdded)
606 {
607 hitsAdded = false;
608
609 for (const CaloHit *const pCaloHit : cosmicRayHitList)
610 {
611 if (std::find(collectedHits.begin(), collectedHits.end(), pCaloHit) != collectedHits.end())
612 continue;
613
614 const float distanceToCollectedHits(std::min(LArMuonLeadingHelper::GetClosestDistance(pCaloHit, deltaRayProjectedPositions),
615 collectedHits.empty() ? std::numeric_limits<float>::max()
616 : LArClusterHelper::GetClosestDistance(pCaloHit->GetPositionVector(), collectedHits)));
617 const float distanceToMuonHits(muonDirection.GetCrossProduct(pCaloHit->GetPositionVector() - positionOnMuon).GetMagnitude());
618
619 if ((std::fabs(distanceToMuonHits - distanceToCollectedHits) < std::numeric_limits<float>::epsilon()) ||
620 (distanceToMuonHits < minDistanceFromMuon) || (distanceToCollectedHits > distanceToMuonHits) ||
621 (distanceToCollectedHits > maxDistanceToCollected))
622 {
623 continue;
624 }
625
626 collectedHits.push_back(pCaloHit);
627 hitsAdded = true;
628 }
629 }
630}
631
632//------------------------------------------------------------------------------------------------------------------------------------------
633
634template <typename T>
636 const Cluster *const pDeltaRayCluster, CartesianVector &positionOnMuon, CartesianVector &muonDirection) const
637{
638 CaloHitList deltaRayHitList;
639 pDeltaRayCluster->GetOrderedCaloHitList().FillCaloHitList(deltaRayHitList);
640
641 CartesianPointVector deltaRayProjectedPositions;
642
643 for (const CaloHit *const pCaloHit : deltaRayHitList)
644 deltaRayProjectedPositions.push_back(pCaloHit->GetPositionVector());
645
646 return this->ParameteriseMuon(
647 pParentMuon, deltaRayProjectedPositions, LArClusterHelper::GetClusterHitType(pDeltaRayCluster), positionOnMuon, muonDirection);
648}
649
650//------------------------------------------------------------------------------------------------------------------------------------------
651
652template <typename T>
654 const CartesianPointVector &deltaRayProjectedPositions, const HitType hitType, CartesianVector &positionOnMuon, CartesianVector &muonDirection) const
655{
656 ClusterList muonClusterList;
657 LArPfoHelper::GetClusters(pParentMuon, hitType, muonClusterList);
658
659 if (muonClusterList.size() != 1)
660 return STATUS_CODE_NOT_FOUND;
661
662 CartesianPointVector muonProjectedPositions;
663 if (this->ProjectMuonPositions(hitType, pParentMuon, muonProjectedPositions) != STATUS_CODE_SUCCESS)
664 return STATUS_CODE_NOT_FOUND;
665
666 const Cluster *const pMuonCluster(muonClusterList.front());
667 const float slidingFitPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
668 const TwoDSlidingFitResult slidingFitResult(pMuonCluster, 40, slidingFitPitch);
669
670 CartesianVector deltaRayVertex(0.f, 0.f, 0.f), muonVertex(0.f, 0.f, 0.f);
671 LArMuonLeadingHelper::GetClosestPositions(deltaRayProjectedPositions, pMuonCluster, deltaRayVertex, muonVertex);
672
674 muonVertex, muonProjectedPositions, pMuonCluster, m_maxDistanceToCluster, m_maxDistanceToReferencePoint, positionOnMuon));
675
676 if (status != STATUS_CODE_SUCCESS)
677 return STATUS_CODE_NOT_FOUND;
678
679 float rL(0.f), rT(0.f);
680 slidingFitResult.GetLocalPosition(positionOnMuon, rL, rT);
681
682 if (slidingFitResult.GetGlobalFitDirection(rL, muonDirection) != STATUS_CODE_SUCCESS)
683 return STATUS_CODE_NOT_FOUND;
684
685 return STATUS_CODE_SUCCESS;
686}
687
688//------------------------------------------------------------------------------------------------------------------------------------------
689
690template <typename T>
691void NViewDeltaRayMatchingAlgorithm<T>::SplitMuonCluster(const std::string &clusterListName, const Cluster *const pMuonCluster,
692 const CaloHitList &collectedHits, const Cluster *&pDeltaRayCluster) const
693{
694 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Cluster>(*this, clusterListName));
695
696 CaloHitList muonCaloHitList;
697 pMuonCluster->GetOrderedCaloHitList().FillCaloHitList(muonCaloHitList);
698
699 for (const CaloHit *const pCaloHit : muonCaloHitList)
700 {
701 if (std::find(collectedHits.begin(), collectedHits.end(), pCaloHit) != collectedHits.end())
702 {
703 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::RemoveFromCluster(*this, pMuonCluster, pCaloHit));
704
705 if (!pDeltaRayCluster)
706 {
707 const ClusterList *pTemporaryList(nullptr);
708 std::string temporaryListName, currentListName;
709 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentListName<Cluster>(*this, currentListName));
710 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
711 PandoraContentApi::CreateTemporaryListAndSetCurrent<ClusterList>(*this, pTemporaryList, temporaryListName));
712
713 PandoraContentApi::Cluster::Parameters parameters;
714 parameters.m_caloHitList.push_back(pCaloHit);
715
716 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::Create(*this, parameters, pDeltaRayCluster));
717 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Cluster>(*this, temporaryListName, currentListName));
718 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Cluster>(*this, currentListName));
719 }
720 else
721 {
722 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToCluster(*this, pDeltaRayCluster, pCaloHit));
723 }
724 }
725 }
726}
727
728//------------------------------------------------------------------------------------------------------------------------------------------
729
730template <typename T>
732{
733 std::sort(protoParticleVector.begin(), protoParticleVector.end(), [](const ProtoParticle &a, const ProtoParticle &b) -> bool {
734 unsigned int aHitTotal(0);
735 for (const Cluster *const pCluster : a.m_clusterList)
736 aHitTotal += pCluster->GetNCaloHits();
737
738 unsigned int bHitTotal(0);
739 for (const Cluster *const pCluster : b.m_clusterList)
740 bHitTotal += pCluster->GetNCaloHits();
741
742 return (aHitTotal > bHitTotal);
743 });
744
745 for (ProtoParticle protoParticle : protoParticleVector)
746 {
747 float longestSpan(-std::numeric_limits<float>::max()), spanMinX(0.f), spanMaxX(0.f);
748
749 for (const Cluster *const pCluster : protoParticle.m_clusterList)
750 {
751 float minX(0.f), maxX(0.f);
752 pCluster->GetClusterSpanX(minX, maxX);
753
754 const float span(maxX - minX);
755
756 if (span > longestSpan)
757 {
758 longestSpan = span;
759 spanMinX = minX;
760 spanMaxX = maxX;
761 }
762 }
763
764 for (const Cluster *const pCluster : protoParticle.m_clusterList)
765 {
766 ClusterList collectedClusters;
767 this->CollectStrayClusters(pCluster, spanMinX, spanMaxX, collectedClusters);
768
769 if (!collectedClusters.empty())
770 this->AddInStrayClusters(pCluster, collectedClusters);
771 }
772 }
773
774 return (this->CreateThreeDParticles(protoParticleVector));
775}
776
777//------------------------------------------------------------------------------------------------------------------------------------------
778
779template <typename T>
781 const Cluster *const pClusterToEnlarge, const float rangeMinX, const float rangeMaxX, ClusterList &collectedClusters)
782{
783 const HitType hitType(LArClusterHelper::GetClusterHitType(pClusterToEnlarge));
784 const ClusterList &strayClusterList((hitType == TPC_VIEW_U) ? m_strayClusterListU : (hitType == TPC_VIEW_V) ? m_strayClusterListV : m_strayClusterListW);
785 const DeltaRayMatchingContainers::ClusterProximityMap &clusterProximityMap(m_deltaRayMatchingContainers.GetClusterProximityMap(hitType));
786 const DeltaRayMatchingContainers::ClusterProximityMap::const_iterator clusterProximityIter(clusterProximityMap.find(pClusterToEnlarge));
787
788 if (clusterProximityIter == clusterProximityMap.end())
789 return;
790
791 for (const Cluster *const pNearbyCluster : clusterProximityIter->second)
792 {
793 if (std::find(strayClusterList.begin(), strayClusterList.end(), pNearbyCluster) == strayClusterList.end())
794 continue;
795
796 float xMin(-std::numeric_limits<float>::max()), xMax(+std::numeric_limits<float>::max());
797 pNearbyCluster->GetClusterSpanX(xMin, xMax);
798
799 if (!(((xMin > rangeMinX) && (xMin < rangeMaxX)) || ((xMax > rangeMinX) && (xMax < rangeMaxX))))
800 continue;
801
802 if (LArClusterHelper::GetClosestDistance(pClusterToEnlarge, pNearbyCluster) > m_strayClusterSeparation)
803 continue;
804
805 if (std::find(collectedClusters.begin(), collectedClusters.end(), pNearbyCluster) == collectedClusters.end())
806 collectedClusters.push_back(pNearbyCluster);
807 }
808}
809
810//------------------------------------------------------------------------------------------------------------------------------------------
811
812template <typename T>
813void NViewDeltaRayMatchingAlgorithm<T>::AddInStrayClusters(const Cluster *const pClusterToEnlarge, const ClusterList &collectedClusters)
814{
815 this->UpdateUponDeletion(pClusterToEnlarge);
816
817 for (const Cluster *const pCollectedCluster : collectedClusters)
818 {
819 this->UpdateUponDeletion(pCollectedCluster);
820
821 std::string clusterListName(this->GetClusterListName(LArClusterHelper::GetClusterHitType(pClusterToEnlarge)));
822 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
823 PandoraContentApi::MergeAndDeleteClusters(*this, pClusterToEnlarge, pCollectedCluster, clusterListName, clusterListName));
824 }
825
826 m_deltaRayMatchingContainers.AddClustersToContainers({pClusterToEnlarge}, {nullptr});
827}
828
829//------------------------------------------------------------------------------------------------------------------------------------------
830
831template <typename T>
833{
834 const HitType hitType(LArClusterHelper::GetClusterHitType(pDeletedCluster));
835 ClusterList &strayClusterList((hitType == TPC_VIEW_U) ? m_strayClusterListU : (hitType == TPC_VIEW_V) ? m_strayClusterListV : m_strayClusterListW);
836 const ClusterList::const_iterator strayClusterIter(std::find(strayClusterList.begin(), strayClusterList.end(), pDeletedCluster));
837
838 if (strayClusterIter != strayClusterList.end())
839 strayClusterList.erase(strayClusterIter);
840
841 const DeltaRayMatchingContainers::ClusterToPfoMap &clusterToPfoMap(m_deltaRayMatchingContainers.GetClusterToPfoMap(hitType));
842 const bool isMuonCluster(clusterToPfoMap.find(pDeletedCluster) != clusterToPfoMap.end());
843
844 m_deltaRayMatchingContainers.RemoveClusterFromContainers(pDeletedCluster);
845
846 if (!isMuonCluster)
848}
849
850//------------------------------------------------------------------------------------------------------------------------------------------
851
852template <typename T>
854{
855 m_deltaRayMatchingContainers.AddClustersToContainers(newClusterVector, pfoVector);
856
857 for (unsigned int i = 0; i < newClusterVector.size(); i++)
858 {
859 const Cluster *const pNewCluster(newClusterVector.at(i));
860 const ParticleFlowObject *const pMuonPfo(pfoVector.at(i));
861
862 // ATTN: Only add delta ray clusters into the tensor
863 if (!pMuonPfo)
865 }
866}
867
868//------------------------------------------------------------------------------------------------------------------------------------------
869
870template <typename T>
872{
873 m_deltaRayMatchingContainers.ClearContainers();
874
875 m_strayClusterListU.clear();
876 m_strayClusterListV.clear();
877 m_strayClusterListW.clear();
878
880}
881
882//------------------------------------------------------------------------------------------------------------------------------------------
883
884template <typename T>
886{
887 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "MuonPfoListName", m_muonPfoListName));
888
889 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
890 XmlHelper::ReadValue(xmlHandle, "SearchRegion1D", m_deltaRayMatchingContainers.m_searchRegion1D));
891
892 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "PseudoChi2Cut", m_pseudoChi2Cut));
893
894 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "OverlapWindow", m_xOverlapWindow));
895
897 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinMatchedFraction", m_minMatchedFraction));
898
900 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinMatchedPoints", m_minMatchedPoints));
901
903 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinProjectedPositions", m_minProjectedPositions));
904
905 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
906 XmlHelper::ReadValue(xmlHandle, "MaxCosmicRayHitFraction", m_maxCosmicRayHitFraction));
907
909 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxDistanceToCluster", m_maxDistanceToCluster));
910
911 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
912 XmlHelper::ReadValue(xmlHandle, "MaxDistanceToReferencePoint", m_maxDistanceToReferencePoint));
913
915 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "StrayClusterSeparation", m_strayClusterSeparation));
916
918}
919
920//------------------------------------------------------------------------------------------------------------------------------------------
921
924
925} // namespace lar_content
Grouping of header files for many classes of use in particle flow algorithms.
Header file for the kd tree linker algo template class.
Header file for the cluster helper class.
Header file for the geometry helper class.
Header file for the muon leading helper class.
Header file for the pfo helper class.
Header file for the lar track overlap result class.
Header file for the lar track two view overlap result class.
Header file for the lar two dimensional sliding fit result 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
Header file for the three view matching control class.
Header file for the two view matching control class.
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 MergeAndDeleteClusters(const pandora::Algorithm &algorithm, const pandora::Cluster *const pClusterToEnlarge, const pandora::Cluster *const pClusterToDelete)
Merge two clusters in the current list, enlarging one cluster and deleting the second.
static pandora::StatusCode AddToCluster(const pandora::Algorithm &algorithm, const pandora::Cluster *const pCluster, const T *const pT)
Add a calo hit, or a list of calo hits, to a cluster.
static pandora::StatusCode RemoveFromCluster(const pandora::Algorithm &algorithm, const pandora::Cluster *const pCluster, const pandora::CaloHit *const pCaloHit)
Remove a calo hit from a cluster. Note this function will not remove the final calo hit from a cluste...
static pandora::StatusCode GetList(const pandora::Algorithm &algorithm, const std::string &listName, const T *&pT)
Get a named list.
std::map< const pandora::Cluster *, pandora::ClusterList > ClusterProximityMap
std::map< const pandora::Cluster *, const pandora::ParticleFlowObject * > ClusterToPfoMap
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.
static float MergeTwoPositions(const pandora::Pandora &pandora, const pandora::HitType view1, const pandora::HitType view2, const float position1, const float position2)
Merge two views (U,V) to give a third view (Z).
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
static pandora::StatusCode GetClosestPosition(const pandora::CartesianVector &referencePoint, const pandora::CartesianPointVector &cartesianPointVector, const pandora::Cluster *const pCluster, const float maxDistanceToCluster, const float maxDistanceToReferencePoint, pandora::CartesianVector &closestPosition)
Get the closest position from an input list of projected positions that lies close to both a referenc...
static float GetClosestDistance(const pandora::Cluster *const pCluster, const pandora::CartesianPointVector &cartesianPointVector)
Get closest distance between a specified cluster and list of positions.
static void GetClosestPositions(const pandora::CartesianPointVector &cartesianPointVector1, const pandora::Cluster *const pCluster2, pandora::CartesianVector &outputPosition1, pandora::CartesianVector &outputPosition2)
Get the closest positions between a list of positions and a cluster.
static void GetClusters(const pandora::PfoList &pfoList, const pandora::HitType &hitType, pandora::ClusterList &clusterList)
Get a list of clusters of a particular hit type from a list of pfos.
void CollectStrayClusters(const pandora::Cluster *const pClusterToEnlarge, const float rangeMinX, const float rangeMaxX, pandora::ClusterList &collectedClusters)
Collect the stray clusters that are close to a specified cluster and that lie within a given x range.
void UpdateUponDeletion(const pandora::Cluster *const pDeletedCluster)
Update to reflect cluster deletion.
void GetClusterSpanX(const pandora::CaloHitList &caloHitList, float &xMin, float &xMax) const
Calculate the xSpan of a list of CaloHits.
pandora::StatusCode CollectHitsFromMuon(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, const pandora::Cluster *const pThirdViewCluster, const pandora::ParticleFlowObject *const pParentMuon, const float minDistanceFromMuon, const float maxDistanceToCollected, pandora::CaloHitList &collectedHits) const
In one view, pull out any hits from a cosmic ray cluster that belong to the child delta ray cluster.
pandora::StatusCode ProjectMuonPositions(const pandora::HitType &thirdViewHitType, const pandora::ParticleFlowObject *const pParentMuon, pandora::CartesianPointVector &projectedPositions) const
Use two views of a cosmic ray pfo to calculate projected positions in a given the third view.
void UpdateForNewClusters(const pandora::ClusterVector &newClusterVector, const pandora::PfoVector &pfoVector)
Add a new cluster to algorithm ownership maps and, if it a delta ray cluster, to the underlying match...
void AddInStrayClusters(const pandora::Cluster *const pClusterToEnlarge, const pandora::ClusterList &collectedClusters)
Merge in the collected stray clusters of a given delta ray cluster.
void GetNearbyMuonPfos(const pandora::Cluster *const pCluster, pandora::ClusterList &consideredClusters, pandora::PfoList &nearbyMuonPfos) const
Use the cluster proximity map to travel along paths of nearby clusters finding the cosmic ray cluster...
pandora::StatusCode PerformThreeViewMatching(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, const pandora::Cluster *const pCluster3, float &reducedChiSquared) const
To determine how well three clusters (one in each view) map onto one another expressing this in terms...
void FillStrayClusterList(const pandora::HitType hitType)
Fill the stray cluster list with clusters that do not pass the tensor threshold requirement.
void TidyUp()
Tidy member variables in derived class.
pandora::StatusCode ParameteriseMuon(const pandora::ParticleFlowObject *const pParentMuon, const pandora::Cluster *const pDeltaRayCluster, pandora::CartesianVector &positionOnMuon, pandora::CartesianVector &muonDirection) const
Parameterise the projection of a cosmic ray track in order to avoid poor/sparse projections.
void SplitMuonCluster(const std::string &clusterListName, const pandora::Cluster *const pMuonCluster, const pandora::CaloHitList &collectedHits, const pandora::Cluster *&pDeltaRayCluster) const
Move a list of hits from a cosmic ray cluster into the given child delta ray cluster.
pandora::StatusCode GetProjectedPositions(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, pandora::CartesianPointVector &projectedPositions) const
Use two clusters from different views to calculate projected positions in the remaining third view.
bool CreatePfos(ProtoParticleVector &protoParticleVector)
Create delta ray pfos maxmising completeness by searching for and merging in any stray clusters.
void SelectInputClusters(const pandora::ClusterList *const pInputClusterList, pandora::ClusterList &selectedClusterList) const
Select a subset of input clusters for processing in this algorithm.
void PrepareInputClusters(pandora::ClusterList &preparedClusterList)
Perform any preparatory steps required on the input clusters, e.g. caching expensive fit results.
pandora::StatusCode GetClusterSpanZ(const pandora::CaloHitList &caloHitList, const float xMin, const float xMax, float &zMin, float &zMax) const
Calculate the zSpan of a list of CaloHits in a specified x range.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
pandora::StatusCode GetMuonCluster(const pandora::PfoList &commonMuonPfoList, const pandora::HitType hitType, const pandora::Cluster *&pMuonCluster) const
Return the cluster of the common cosmic ray pfo in a given view (function demands there to be only on...
void UpdateUponDeletion(const pandora::Cluster *const pDeletedCluster)
Update to reflect cluster deletion.
void UpdateForNewCluster(const pandora::Cluster *const pNewCluster)
Update to reflect addition of a new cluster to the problem space.
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
virtual void TidyUp()
Tidy member variables in derived class.
void GetLocalPosition(const pandora::CartesianVector &position, float &rL, float &rT) const
Get local sliding fit coordinates for a given global position.
pandora::StatusCode GetGlobalFitDirection(const float rL, pandora::CartesianVector &direction) const
Get global fit direction for a given longitudinal coordinate.
XOverlap class.
Definition LArXOverlap.h:18
CaloHit class.
Definition CaloHit.h:26
CartesianVector class.
float GetMagnitude() const
Get the magnitude.
CartesianVector GetCrossProduct(const CartesianVector &rhs) const
Get the cross product of the cartesian vector with a second cartesian vector.
Cluster class.
Definition Cluster.h:31
unsigned int GetNCaloHits() const
Get the number of calo hits in the cluster.
Definition Cluster.h:484
const OrderedCaloHitList & GetOrderedCaloHitList() const
Get the ordered calo hit list.
Definition Cluster.h:470
void GetClusterSpanX(float &xmin, float &xmax) const
Get minimum and maximum X positions of the calo hits in this cluster.
Definition Cluster.cc:169
void GetClusterSpanZ(const float xmin, const float xmax, float &zmin, float &zmax) const
Get upper and lower Z positions of the calo hits in a cluster in range xmin to xmax.
Definition Cluster.cc:198
void FillCaloHitList(CaloHitList &caloHitList) const
Fill a provided calo hit list with all the calo hits in the ordered calo hit list.
ParticleFlowObject class.
StatusCodeException class.
StatusCode GetStatusCode() const
Get status code.
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< ProtoParticle > ProtoParticleVector
HitType
Calorimeter hit type enum.
std::vector< const Cluster * > ClusterVector
MANAGED_CONTAINER< const Cluster * > ClusterList
std::vector< const ParticleFlowObject * > PfoVector
std::vector< CartesianVector > CartesianPointVector
MANAGED_CONTAINER< const CaloHit * > CaloHitList
StatusCode
The StatusCode enum.
MANAGED_CONTAINER< const ParticleFlowObject * > PfoList