9 #include "Pandora/AlgorithmHeaders.h" 34 m_pseudoChi2Cut(1.5
f),
35 m_xOverlapWindow(1.
f),
36 m_minMatchedFraction(0.5),
37 m_minMatchedPoints(3),
38 m_minProjectedPositions(3),
39 m_maxCosmicRayHitFraction(0.05
f),
40 m_maxDistanceToCluster(0.5
f),
41 m_maxDistanceToReferencePoint(5.
f),
42 m_strayClusterSeparation(2.
f)
51 for (
const Cluster *
const pCluster : *pInputClusterList)
54 selectedClusterList.push_back(pCluster);
63 if (preparedClusterList.empty())
66 const PfoList *pMuonPfoList(
nullptr);
68 PANDORA_THROW_RESULT_IF_AND_IF(
69 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*
this,
m_muonPfoListName, pMuonPfoList));
71 if ((!pMuonPfoList) || pMuonPfoList->empty())
91 for (
const Cluster *
const pCluster : inputClusterList)
94 strayClusterList.push_back(pCluster);
100 template <
typename T>
103 if (commonMuonPfoList.size() != 1)
104 return STATUS_CODE_NOT_FOUND;
106 ClusterList muonClusterList;
109 if (muonClusterList.size() != 1)
110 return STATUS_CODE_NOT_FOUND;
112 pMuonCluster = muonClusterList.front();
114 return STATUS_CODE_SUCCESS;
119 template <
typename T>
126 consideredClusters.push_back(pCluster);
130 if (clusterProximityIter == clusterProximityMap.end())
133 for (
const Cluster *
const pNearbyCluster : clusterProximityIter->second)
135 if (std::find(consideredClusters.begin(), consideredClusters.end(), pNearbyCluster) != consideredClusters.end())
140 if (pfoIter != clusterToPfoMap.end())
142 if (std::find(nearbyMuonPfos.begin(), nearbyMuonPfos.end(), pfoIter->second) == nearbyMuonPfos.end())
143 nearbyMuonPfos.push_back(pfoIter->second);
154 template <
typename T>
156 const Cluster *
const pCluster1,
const Cluster *
const pCluster2,
const Cluster *
const pCluster3,
float &reducedChiSquared)
const 158 float chiSquaredSum(0.
f);
159 unsigned int nSamplingPoints(0), nMatchedSamplingPoints(0);
162 if (this->
PerformThreeViewMatching(pCluster1, pCluster2, pCluster3, chiSquaredSum, nSamplingPoints, nMatchedSamplingPoints,
163 xThreeViewOverlapObject) == STATUS_CODE_NOT_FOUND)
164 return STATUS_CODE_NOT_FOUND;
166 if (nSamplingPoints == 0)
167 return STATUS_CODE_NOT_FOUND;
169 reducedChiSquared = chiSquaredSum / nSamplingPoints;
171 return STATUS_CODE_SUCCESS;
176 template <
typename T>
178 const Cluster *
const pClusterW,
float &chiSquaredSum,
unsigned int &nSamplingPoints,
unsigned int &nMatchedSamplingPoints,
XOverlap &xOverlapObject)
const 180 float xMinU(-std::numeric_limits<float>::max()), xMaxU(+std::numeric_limits<float>::max());
181 float xMinV(-std::numeric_limits<float>::max()), xMaxV(+std::numeric_limits<float>::max());
182 float xMinW(-std::numeric_limits<float>::max()), xMaxW(+std::numeric_limits<float>::max());
184 pClusterU->GetClusterSpanX(xMinU, xMaxU);
185 pClusterV->GetClusterSpanX(xMinV, xMaxV);
186 pClusterW->GetClusterSpanX(xMinW, xMaxW);
189 const float xMinCentre(std::max(xMinU, std::max(xMinV, xMinW)));
190 const float xMaxCentre(std::min(xMaxU, std::min(xMaxV, xMaxW)));
191 const float xCentreOverlap(xMaxCentre - xMinCentre);
193 if (xCentreOverlap < std::numeric_limits<float>::epsilon())
194 return STATUS_CODE_NOT_FOUND;
197 const float xMin(std::max(xMinU, std::max(xMinV, xMinW)) - xPitch);
198 const float xMax(std::min(xMaxU, std::min(xMaxV, xMaxW)) + xPitch);
199 const float xOverlap(xMax - xMin);
207 const float pitchMax{std::max({pitchU, pitchV, pitchW})};
209 if (hitTypeU == hitTypeV || hitTypeU == hitTypeW || hitTypeV == hitTypeW)
210 return STATUS_CODE_FAILURE;
212 const unsigned int nPoints(1 + static_cast<unsigned int>(xOverlap / xPitch));
216 nMatchedSamplingPoints = 0;
218 for (
unsigned int n = 0;
n < nPoints; ++
n)
220 const float x(xMin + (xMax - xMin) * (static_cast<float>(
n) + 0.5
f) / static_cast<float>(nPoints));
221 const float xmin(x - xPitch);
222 const float xmax(x + xPitch);
226 float zMinU(0.
f), zMinV(0.
f), zMinW(0.
f), zMaxU(0.
f), zMaxV(0.
f), zMaxW(0.
f);
227 pClusterU->GetClusterSpanZ(xmin, xmax, zMinU, zMaxU);
228 pClusterV->GetClusterSpanZ(xmin, xmax, zMinV, zMaxV);
229 pClusterW->GetClusterSpanZ(xmin, xmax, zMinW, zMaxW);
231 const float zU(0.5
f * (zMinU + zMaxU));
232 const float zV(0.5
f * (zMinV + zMaxV));
233 const float zW(0.5
f * (zMinW + zMaxW));
235 const float dzU(zMaxU - zMinU);
236 const float dzV(zMaxV - zMinV);
237 const float dzW(zMaxW - zMinW);
238 const float dzPitch(pitchMax);
246 const float deltaSquared(((zU - zprojU) * (zU - zprojU) + (zV - zprojV) * (zV - zprojV) + (zW - zprojW) * (zW - zprojW)) / 3.
f);
247 const float sigmaSquared(dzU * dzU + dzV * dzV + dzW * dzW + dzPitch * dzPitch);
248 const float pseudoChi2(deltaSquared / sigmaSquared);
250 chiSquaredSum += pseudoChi2;
253 ++nMatchedSamplingPoints;
255 catch (StatusCodeException &statusCodeException)
257 if (statusCodeException.GetStatusCode() != STATUS_CODE_NOT_FOUND)
258 return statusCodeException.GetStatusCode();
265 if (nSamplingPoints == 0)
266 return STATUS_CODE_NOT_FOUND;
268 const float matchedFraction(static_cast<float>(nMatchedSamplingPoints) / static_cast<float>(nSamplingPoints));
271 return STATUS_CODE_NOT_FOUND;
273 xOverlapObject =
XOverlap(xMinU, xMaxU, xMinV, xMaxV, xMinW, xMaxW, xCentreOverlap);
275 return STATUS_CODE_SUCCESS;
280 template <
typename T>
282 const CaloHitList &pCluster1,
const CaloHitList &pCluster2,
const CaloHitList &pCluster3,
float &reducedChiSquared)
const 284 float chiSquaredSum(0.
f);
285 unsigned int nSamplingPoints(0), nMatchedSamplingPoints(0);
288 if (this->
PerformThreeViewMatching(pCluster1, pCluster2, pCluster3, chiSquaredSum, nSamplingPoints, nMatchedSamplingPoints,
289 xThreeViewOverlapObject) == STATUS_CODE_NOT_FOUND)
290 return STATUS_CODE_NOT_FOUND;
292 if (nSamplingPoints == 0)
293 return STATUS_CODE_NOT_FOUND;
295 reducedChiSquared = chiSquaredSum / nSamplingPoints;
297 return STATUS_CODE_SUCCESS;
302 template <
typename T>
304 const CaloHitList &clusterW,
float &chiSquaredSum,
unsigned int &nSamplingPoints,
unsigned int &nMatchedSamplingPoints,
XOverlap &xOverlapObject)
const 306 float xMinU(-std::numeric_limits<float>::max()), xMaxU(+std::numeric_limits<float>::max());
307 float xMinV(-std::numeric_limits<float>::max()), xMaxV(+std::numeric_limits<float>::max());
308 float xMinW(-std::numeric_limits<float>::max()), xMaxW(+std::numeric_limits<float>::max());
315 const float xMinCentre(std::max(xMinU, std::max(xMinV, xMinW)));
316 const float xMaxCentre(std::min(xMaxU, std::min(xMaxV, xMaxW)));
317 const float xCentreOverlap(xMaxCentre - xMinCentre);
319 if (xCentreOverlap < std::numeric_limits<float>::epsilon())
320 return STATUS_CODE_NOT_FOUND;
323 const float xMin(std::max(xMinU, std::max(xMinV, xMinW)) - xPitch);
324 const float xMax(std::min(xMaxU, std::min(xMaxV, xMaxW)) + xPitch);
325 const float xOverlap(xMax - xMin);
327 const HitType hitTypeU(clusterU.front()->GetHitType());
328 const HitType hitTypeV(clusterV.front()->GetHitType());
329 const HitType hitTypeW(clusterW.front()->GetHitType());
333 const float pitchMax{std::max({pitchU, pitchV, pitchW})};
335 if (hitTypeU == hitTypeV || hitTypeU == hitTypeW || hitTypeV == hitTypeW)
336 return STATUS_CODE_FAILURE;
338 const unsigned int nPoints(1 + static_cast<unsigned int>(xOverlap / xPitch));
342 nMatchedSamplingPoints = 0;
344 for (
unsigned int n = 0;
n < nPoints; ++
n)
346 const float x(xMin + (xMax - xMin) * (static_cast<float>(
n) + 0.5
f) / static_cast<float>(nPoints));
347 const float xmin(x - xPitch);
348 const float xmax(x + xPitch);
352 float zMinU(0.
f), zMinV(0.
f), zMinW(0.
f), zMaxU(0.
f), zMaxV(0.
f), zMaxW(0.
f);
357 const float zU(0.5
f * (zMinU + zMaxU));
358 const float zV(0.5
f * (zMinV + zMaxV));
359 const float zW(0.5
f * (zMinW + zMaxW));
361 const float dzU(zMaxU - zMinU);
362 const float dzV(zMaxV - zMinV);
363 const float dzW(zMaxW - zMinW);
364 const float dzPitch(pitchMax);
372 const float deltaSquared(((zU - zprojU) * (zU - zprojU) + (zV - zprojV) * (zV - zprojV) + (zW - zprojW) * (zW - zprojW)) / 3.
f);
373 const float sigmaSquared(dzU * dzU + dzV * dzV + dzW * dzW + dzPitch * dzPitch);
374 const float pseudoChi2(deltaSquared / sigmaSquared);
376 chiSquaredSum += pseudoChi2;
379 ++nMatchedSamplingPoints;
381 catch (StatusCodeException &statusCodeException)
383 if (statusCodeException.GetStatusCode() != STATUS_CODE_NOT_FOUND)
384 return statusCodeException.GetStatusCode();
391 if (nSamplingPoints == 0)
392 return STATUS_CODE_NOT_FOUND;
394 const float matchedFraction(static_cast<float>(nMatchedSamplingPoints) / static_cast<float>(nSamplingPoints));
397 return STATUS_CODE_NOT_FOUND;
399 xOverlapObject =
XOverlap(xMinU, xMaxU, xMinV, xMaxV, xMinW, xMaxW, xCentreOverlap);
401 return STATUS_CODE_SUCCESS;
406 template <
typename T>
409 xMin = std::numeric_limits<float>::max();
410 xMax = -std::numeric_limits<float>::max();
412 for (
const CaloHit *
const pCaloHit : caloHitList)
414 const float xCoordinate(pCaloHit->GetPositionVector().GetX());
416 if (xCoordinate < xMin)
419 if (xCoordinate > xMax)
426 template <
typename T>
428 const CaloHitList &caloHitList,
const float xMin,
const float xMax,
float &zMin,
float &zMax)
const 430 zMin = std::numeric_limits<float>::max();
431 zMax = -std::numeric_limits<float>::max();
434 for (
const CaloHit *
const pCaloHit : caloHitList)
436 const float xCoordinate(pCaloHit->GetPositionVector().GetX());
437 const float zCoordinate(pCaloHit->GetPositionVector().GetZ());
439 if ((xCoordinate < xMin) || (xCoordinate > xMax))
444 if (zCoordinate < zMin)
447 if (zCoordinate > zMax)
452 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
454 return STATUS_CODE_SUCCESS;
459 template <
typename T>
461 const HitType &thirdViewHitType,
const ParticleFlowObject *
const pParentMuon, CartesianPointVector &projectedPositions)
const 463 ClusterList muonClusterList1, muonClusterList2;
465 HitTypeVector hitTypes({TPC_VIEW_U, TPC_VIEW_V, TPC_VIEW_W});
467 hitTypes.erase(std::find(hitTypes.begin(), hitTypes.end(), thirdViewHitType));
472 if ((muonClusterList1.size() != 1) || (muonClusterList2.size() != 1))
473 return STATUS_CODE_NOT_FOUND;
475 return (this->
GetProjectedPositions(muonClusterList1.front(), muonClusterList2.front(), projectedPositions));
480 template <
typename T>
482 const Cluster *
const pCluster1,
const Cluster *
const pCluster2, CartesianPointVector &projectedPositions)
const 484 float xMin1(0.
f), xMax1(0.
f), xMin2(0.
f), xMax2(0.
f);
485 pCluster1->GetClusterSpanX(xMin1, xMax1);
486 pCluster2->GetClusterSpanX(xMin2, xMax2);
489 const float xMin(std::max(xMin1, xMin2) - xPitch);
490 const float xMax(std::min(xMax1, xMax2) + xPitch);
491 const float xOverlap(xMax - xMin);
493 if (xOverlap < std::numeric_limits<float>::epsilon())
494 return STATUS_CODE_NOT_FOUND;
499 if (hitType1 == hitType2)
500 throw StatusCodeException(STATUS_CODE_FAILURE);
502 const unsigned int nPoints(1 + static_cast<unsigned int>(xOverlap / xPitch));
505 for (
unsigned int n = 0;
n < nPoints; ++
n)
507 const float x(xMin + (xMax - xMin) * (static_cast<float>(
n) + 0.5
f) / static_cast<float>(nPoints));
508 const float xmin(x - xPitch);
509 const float xmax(x + xPitch);
513 float zMin1(0.
f), zMin2(0.
f), zMax1(0.
f), zMax2(0.
f);
514 pCluster1->GetClusterSpanZ(xmin, xmax, zMin1, zMax1);
515 pCluster2->GetClusterSpanZ(xmin, xmax, zMin2, zMax2);
517 const float z1(0.5
f * (zMin1 + zMax1));
518 const float z2(0.5
f * (zMin2 + zMax2));
521 CartesianVector projection(0.
f, 0.
f, 0.
f);
523 this->GetPandora(), hitType1, hitType2, CartesianVector(x, 0.
f, z1), CartesianVector(x, 0.
f, z2), projection, chi2);
525 projectedPositions.push_back(projection);
527 catch (StatusCodeException &statusCodeException)
529 if (statusCodeException.GetStatusCode() != STATUS_CODE_NOT_FOUND)
530 throw statusCodeException.GetStatusCode();
538 return STATUS_CODE_NOT_FOUND;
540 return STATUS_CODE_SUCCESS;
545 template <
typename T>
547 const Cluster *
const pThirdViewCluster,
const ParticleFlowObject *
const pParentMuon,
const float minDistanceFromMuon,
548 const float maxDistanceToCollected, CaloHitList &collectedHits)
const 550 HitType thirdViewHitType(TPC_VIEW_U);
551 CartesianPointVector deltaRayProjectedPositions;
553 if (!pThirdViewCluster)
555 if (this->
GetProjectedPositions(pCluster1, pCluster2, deltaRayProjectedPositions) != STATUS_CODE_SUCCESS)
556 return STATUS_CODE_NOT_FOUND;
558 for (
const HitType hitType : {TPC_VIEW_U, TPC_VIEW_V, TPC_VIEW_W})
562 thirdViewHitType = hitType;
569 CaloHitList deltaRayCaloHitList;
570 pThirdViewCluster->GetOrderedCaloHitList().FillCaloHitList(deltaRayCaloHitList);
572 for (
const CaloHit *
const pCaloHit : deltaRayCaloHitList)
573 deltaRayProjectedPositions.push_back(pCaloHit->GetPositionVector());
578 ClusterList muonClusterList;
581 if (muonClusterList.size() != 1)
582 return STATUS_CODE_NOT_FOUND;
584 const Cluster *
const pMuonCluster(muonClusterList.front());
587 CartesianVector positionOnMuon(0.
f, 0.
f, 0.
f), muonDirection(0.
f, 0.
f, 0.
f);
588 if (this->
ParameteriseMuon(pParentMuon, deltaRayProjectedPositions, thirdViewHitType, positionOnMuon, muonDirection) != STATUS_CODE_SUCCESS)
589 return STATUS_CODE_NOT_FOUND;
592 positionOnMuon, muonDirection, pMuonCluster, deltaRayProjectedPositions, minDistanceFromMuon, maxDistanceToCollected, collectedHits);
594 if (collectedHits.empty())
595 return STATUS_CODE_NOT_FOUND;
599 return STATUS_CODE_NOT_FOUND;
601 return STATUS_CODE_SUCCESS;
606 template <
typename T>
608 const Cluster *
const pMuonCluster,
const CartesianPointVector &deltaRayProjectedPositions,
const float &minDistanceFromMuon,
609 const float maxDistanceToCollected, CaloHitList &collectedHits)
const 611 CaloHitList cosmicRayHitList;
612 pMuonCluster->GetOrderedCaloHitList().FillCaloHitList(cosmicRayHitList);
614 bool hitsAdded(
true);
619 for (
const CaloHit *
const pCaloHit : cosmicRayHitList)
621 if (std::find(collectedHits.begin(), collectedHits.end(), pCaloHit) != collectedHits.end())
625 collectedHits.empty() ? std::numeric_limits<float>::max()
627 const float distanceToMuonHits(muonDirection.GetCrossProduct(pCaloHit->GetPositionVector() - positionOnMuon).GetMagnitude());
629 if ((std::fabs(distanceToMuonHits - distanceToCollectedHits) < std::numeric_limits<float>::epsilon()) ||
630 (distanceToMuonHits < minDistanceFromMuon) || (distanceToCollectedHits > distanceToMuonHits) ||
631 (distanceToCollectedHits > maxDistanceToCollected))
636 collectedHits.push_back(pCaloHit);
644 template <
typename T>
646 const Cluster *
const pDeltaRayCluster, CartesianVector &positionOnMuon, CartesianVector &muonDirection)
const 648 CaloHitList deltaRayHitList;
649 pDeltaRayCluster->GetOrderedCaloHitList().FillCaloHitList(deltaRayHitList);
651 CartesianPointVector deltaRayProjectedPositions;
653 for (
const CaloHit *
const pCaloHit : deltaRayHitList)
654 deltaRayProjectedPositions.push_back(pCaloHit->GetPositionVector());
662 template <
typename T>
664 const CartesianPointVector &deltaRayProjectedPositions,
const HitType hitType, CartesianVector &positionOnMuon, CartesianVector &muonDirection)
const 666 ClusterList muonClusterList;
669 if (muonClusterList.size() != 1)
670 return STATUS_CODE_NOT_FOUND;
672 CartesianPointVector muonProjectedPositions;
673 if (this->
ProjectMuonPositions(hitType, pParentMuon, muonProjectedPositions) != STATUS_CODE_SUCCESS)
674 return STATUS_CODE_NOT_FOUND;
676 const Cluster *
const pMuonCluster(muonClusterList.front());
680 CartesianVector deltaRayVertex(0.
f, 0.
f, 0.
f), muonVertex(0.
f, 0.
f, 0.
f);
686 if (status != STATUS_CODE_SUCCESS)
687 return STATUS_CODE_NOT_FOUND;
689 float rL(0.
f), rT(0.
f);
693 return STATUS_CODE_NOT_FOUND;
695 return STATUS_CODE_SUCCESS;
700 template <
typename T>
702 const CaloHitList &collectedHits,
const Cluster *&pDeltaRayCluster)
const 704 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Cluster>(*
this, clusterListName));
706 CaloHitList muonCaloHitList;
707 pMuonCluster->GetOrderedCaloHitList().FillCaloHitList(muonCaloHitList);
709 for (
const CaloHit *
const pCaloHit : muonCaloHitList)
711 if (std::find(collectedHits.begin(), collectedHits.end(), pCaloHit) != collectedHits.end())
713 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::RemoveFromCluster(*
this, pMuonCluster, pCaloHit));
715 if (!pDeltaRayCluster)
717 const ClusterList *pTemporaryList(
nullptr);
718 std::string temporaryListName, currentListName;
719 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentListName<Cluster>(*
this, currentListName));
720 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
721 PandoraContentApi::CreateTemporaryListAndSetCurrent<ClusterList>(*
this, pTemporaryList, temporaryListName));
723 PandoraContentApi::Cluster::Parameters parameters;
724 parameters.m_caloHitList.push_back(pCaloHit);
726 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::Create(*
this, parameters, pDeltaRayCluster));
727 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Cluster>(*
this, temporaryListName, currentListName));
728 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Cluster>(*
this, currentListName));
732 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToCluster(*
this, pDeltaRayCluster, pCaloHit));
740 template <
typename T>
743 std::sort(protoParticleVector.begin(), protoParticleVector.end(),
746 unsigned int aHitTotal(0);
748 aHitTotal += pCluster->GetNCaloHits();
750 unsigned int bHitTotal(0);
751 for (
const Cluster *
const pCluster : b.m_clusterList)
752 bHitTotal += pCluster->GetNCaloHits();
754 return (aHitTotal > bHitTotal);
759 float longestSpan(-std::numeric_limits<float>::max()), spanMinX(0.
f), spanMaxX(0.
f);
761 for (
const Cluster *
const pCluster : protoParticle.m_clusterList)
763 float minX(0.
f), maxX(0.
f);
764 pCluster->GetClusterSpanX(minX, maxX);
766 const float span(maxX - minX);
768 if (span > longestSpan)
776 for (
const Cluster *
const pCluster : protoParticle.m_clusterList)
778 ClusterList collectedClusters;
781 if (!collectedClusters.empty())
791 template <
typename T>
793 const Cluster *
const pClusterToEnlarge,
const float rangeMinX,
const float rangeMaxX, ClusterList &collectedClusters)
802 if (clusterProximityIter == clusterProximityMap.end())
805 for (
const Cluster *
const pNearbyCluster : clusterProximityIter->second)
807 if (std::find(strayClusterList.begin(), strayClusterList.end(), pNearbyCluster) == strayClusterList.end())
810 float xMin(-std::numeric_limits<float>::max()), xMax(+std::numeric_limits<float>::max());
811 pNearbyCluster->GetClusterSpanX(xMin, xMax);
813 if (!(((xMin > rangeMinX) && (xMin < rangeMaxX)) || ((xMax > rangeMinX) && (xMax < rangeMaxX))))
819 if (std::find(collectedClusters.begin(), collectedClusters.end(), pNearbyCluster) == collectedClusters.end())
820 collectedClusters.push_back(pNearbyCluster);
826 template <
typename T>
831 for (
const Cluster *
const pCollectedCluster : collectedClusters)
836 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
837 PandoraContentApi::MergeAndDeleteClusters(*
this, pClusterToEnlarge, pCollectedCluster, clusterListName, clusterListName));
845 template <
typename T>
854 if (strayClusterIter != strayClusterList.end())
855 strayClusterList.erase(strayClusterIter);
858 const bool isMuonCluster(clusterToPfoMap.find(pDeletedCluster) != clusterToPfoMap.end());
868 template <
typename T>
873 for (
unsigned int i = 0; i < newClusterVector.size(); i++)
875 const Cluster *
const pNewCluster(newClusterVector.at(i));
876 const ParticleFlowObject *
const pMuonPfo(pfoVector.at(i));
886 template <
typename T>
900 template <
typename T>
903 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"MuonPfoListName",
m_muonPfoListName));
905 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
908 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"PseudoChi2Cut",
m_pseudoChi2Cut));
910 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"OverlapWindow",
m_xOverlapWindow));
912 PANDORA_RETURN_RESULT_IF_AND_IF(
913 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinMatchedFraction",
m_minMatchedFraction));
915 PANDORA_RETURN_RESULT_IF_AND_IF(
916 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinMatchedPoints",
m_minMatchedPoints));
918 PANDORA_RETURN_RESULT_IF_AND_IF(
919 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinProjectedPositions",
m_minProjectedPositions));
921 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
924 PANDORA_RETURN_RESULT_IF_AND_IF(
925 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxDistanceToCluster",
m_maxDistanceToCluster));
927 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
930 PANDORA_RETURN_RESULT_IF_AND_IF(
931 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"StrayClusterSeparation",
m_strayClusterSeparation));
std::vector< pandora::HitType > HitTypeVector
void SelectInputClusters(const pandora::ClusterList *const pInputClusterList, pandora::ClusterList &selectedClusterList) const
Select a subset of input clusters for processing in this algorithm.
std::vector< ProtoParticle > ProtoParticleVector
static float GetClosestDistance(const pandora::Cluster *const pCluster, const pandora::CartesianPointVector &cartesianPointVector)
Get closest distance between a specified cluster and list of positions.
Header file for the kd tree linker algo template class.
std::map< const pandora::Cluster *, const pandora::ParticleFlowObject * > ClusterToPfoMap
Header file for the pfo helper class.
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...
const ClusterProximityMap & GetClusterProximityMap(const pandora::HitType hitType) const
Get the mapping of clusters to to their neighbouring clusters.
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.
unsigned int m_minProjectedPositions
The threshold number of projected points for a good projection.
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.
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::ClusterList m_strayClusterListU
The list of U clusters that do not pass the tensor threshold requirement.
virtual void TidyUp()
Tidy member variables in derived class.
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 TidyUp()
Tidy member variables in derived class.
float m_pseudoChi2Cut
Pseudo chi2 cut for three view matching.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
void FillContainers(const pandora::PfoList &inputPfoList, const pandora::ClusterList &inputClusterList1, const pandora::ClusterList &inputClusterList2=pandora::ClusterList(), const pandora::ClusterList &inputClusterList3=pandora::ClusterList())
Fill the HitToClusterMap, the ClusterProximityMap and the ClusterToPfoMap in all input views...
void UpdateUponDeletion(const pandora::Cluster *const pDeletedCluster)
Update to reflect cluster deletion.
void PrepareInputClusters(pandora::ClusterList &preparedClusterList)
Perform any preparatory steps required on the input clusters, e.g. caching expensive fit results...
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 GetClusterSpanX(const pandora::CaloHitList &caloHitList, float &xMin, float &xMax) const
Calculate the xSpan of a list of CaloHits.
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 UpdateUponDeletion(const pandora::Cluster *const pDeletedCluster)
Update to reflect cluster deletion.
Header file for the geometry helper class.
void UpdateForNewCluster(const pandora::Cluster *const pNewCluster)
Update to reflect addition of a new cluster to the problem space.
float m_xOverlapWindow
The maximum allowed displacement in x position.
std::string m_muonPfoListName
The list of reconstructed cosmic ray pfos.
virtual bool DoesClusterPassTensorThreshold(const pandora::Cluster *const pCluster) const =0
To check whether a given cluster meets the requirements to be added into the matching container (tens...
Header file for the cluster helper class.
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Header file for the muon leading helper 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 AddClustersToContainers(const pandora::ClusterVector &newClusterVector, const pandora::PfoVector &pfoVector)
Add a list of clusters to the hit to cluster and cluster proximity maps and, if appropriate, to the cluster to pfo map.
Header file for the lar two dimensional sliding fit result class.
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.
void FillStrayClusterList(const pandora::HitType hitType)
Fill the stray cluster list with clusters that do not pass the tensor threshold requirement.
pandora::ClusterList m_strayClusterListV
The list of V clusters that do not pass the tensor threshold requirement.
pandora::ClusterList m_clusterList
List of 2D clusters in a 3D proto particle.
pandora::ClusterList m_strayClusterListW
The list of W clusters that do not pass the tensor threshold requirement.
const pandora::ClusterList & GetInputClusterList(const pandora::HitType hitType) const
Get the input cluster list corresponding to a specified hit type.
const ClusterToPfoMap & GetClusterToPfoMap(const pandora::HitType hitType) const
Get the mapping of clusters to the pfos to which they belong.
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).
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.
static float GetWirePitch(const pandora::Pandora &pandora, const pandora::HitType view, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
void AddInStrayClusters(const pandora::Cluster *const pClusterToEnlarge, const pandora::ClusterList &collectedClusters)
Merge in the collected stray clusters of a given delta ray cluster.
float m_strayClusterSeparation
The maximum allowed separation of a stray cluster and a delta ray cluster for merge.
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...
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...
float m_maxDistanceToReferencePoint
the maximum distance of a projected point to the cosmic ray vertex used when parameterising the cosmi...
pandora::StatusCode GetGlobalFitDirection(const float rL, pandora::CartesianVector &direction) const
Get global fit direction for a given longitudinal coordinate.
std::map< const pandora::Cluster *, pandora::ClusterList > ClusterProximityMap
Header file for the lar track overlap result class.
span(IterB &&b, IterE &&e, Adaptor &&adaptor) -> span< decltype(adaptor(std::forward< IterB >(b))), decltype(adaptor(std::forward< IterE >(e))) >
Header file for the three view matching control class.
const std::string & GetClusterListName(const pandora::HitType hitType) const
Get the cluster list name corresponding to a specified hit type.
virtual bool CreateThreeDParticles(const ProtoParticleVector &protoParticleVector)
Create particles using findings from recent algorithm processing.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
float m_maxCosmicRayHitFraction
The maximum allowed fraction of hits to be removed from the cosmic ray track.
bool CreatePfos(ProtoParticleVector &protoParticleVector)
Create delta ray pfos maxmising completeness by searching for and merging in any stray clusters...
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...
DeltaRayMatchingContainers m_deltaRayMatchingContainers
The class of hit, cluster and pfo ownership and proximity maps.
void ClearContainers()
Empty all algorithm containers.
Header file for the two view matching control class.
void GetLocalPosition(const pandora::CartesianVector &position, float &rL, float &rT) const
Get local sliding fit coordinates for a given global position.
Header file for the lar track two view overlap result class.
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...
TwoDSlidingFitResult class.
NViewDeltaRayMatchingAlgorithm class.
void RemoveClusterFromContainers(const pandora::Cluster *const pDeletedCluster)
Remove an input cluster's hits from the hit to cluster and cluster proximity maps and...
float m_minMatchedFraction
The threshold matched fraction of sampling points for a good match.
unsigned int m_minMatchedPoints
The threshold number of matched sampling points for a good match.
float m_maxDistanceToCluster
the maximum distance of a projected point to the cosmic ray cluster used when parameterising the cosm...
float m_searchRegion1D
Search region, applied to each dimension, for look-up from kd-tree.
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.