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())
89 for (
const Cluster *
const pCluster : inputClusterList)
92 strayClusterList.push_back(pCluster);
101 if (commonMuonPfoList.size() != 1)
102 return STATUS_CODE_NOT_FOUND;
104 ClusterList muonClusterList;
107 if (muonClusterList.size() != 1)
108 return STATUS_CODE_NOT_FOUND;
110 pMuonCluster = muonClusterList.front();
112 return STATUS_CODE_SUCCESS;
117 template <
typename T>
124 consideredClusters.push_back(pCluster);
128 if (clusterProximityIter == clusterProximityMap.end())
131 for (
const Cluster *
const pNearbyCluster : clusterProximityIter->second)
133 if (std::find(consideredClusters.begin(), consideredClusters.end(), pNearbyCluster) != consideredClusters.end())
138 if (pfoIter != clusterToPfoMap.end())
140 if (std::find(nearbyMuonPfos.begin(), nearbyMuonPfos.end(), pfoIter->second) == nearbyMuonPfos.end())
141 nearbyMuonPfos.push_back(pfoIter->second);
152 template <
typename T>
154 const Cluster *
const pCluster1,
const Cluster *
const pCluster2,
const Cluster *
const pCluster3,
float &reducedChiSquared)
const 156 float chiSquaredSum(0.
f);
157 unsigned int nSamplingPoints(0), nMatchedSamplingPoints(0);
160 if (this->
PerformThreeViewMatching(pCluster1, pCluster2, pCluster3, chiSquaredSum, nSamplingPoints, nMatchedSamplingPoints,
161 xThreeViewOverlapObject) == STATUS_CODE_NOT_FOUND)
162 return STATUS_CODE_NOT_FOUND;
164 if (nSamplingPoints == 0)
165 return STATUS_CODE_NOT_FOUND;
167 reducedChiSquared = chiSquaredSum / nSamplingPoints;
169 return STATUS_CODE_SUCCESS;
174 template <
typename T>
176 const Cluster *
const pClusterW,
float &chiSquaredSum,
unsigned int &nSamplingPoints,
unsigned int &nMatchedSamplingPoints,
XOverlap &xOverlapObject)
const 182 pClusterU->GetClusterSpanX(xMinU, xMaxU);
183 pClusterV->GetClusterSpanX(xMinV, xMaxV);
184 pClusterW->GetClusterSpanX(xMinW, xMaxW);
189 const float xCentreOverlap(xMaxCentre - xMinCentre);
191 if (xCentreOverlap < std::numeric_limits<float>::epsilon())
192 return STATUS_CODE_NOT_FOUND;
197 const float xOverlap(xMax - xMin);
203 if (hitTypeU == hitTypeV || hitTypeU == hitTypeW || hitTypeV == hitTypeW)
204 return STATUS_CODE_FAILURE;
206 const unsigned int nPoints(1 + static_cast<unsigned int>(xOverlap / xPitch));
210 nMatchedSamplingPoints = 0;
212 for (
unsigned int n = 0;
n < nPoints; ++
n)
214 const float x(xMin + (xMax - xMin) * (static_cast<float>(
n) + 0.5
f) / static_cast<float>(nPoints));
215 const float xmin(x - xPitch);
216 const float xmax(x + xPitch);
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.5
f * (zMinU + zMaxU));
226 const float zV(0.5
f * (zMinV + zMaxV));
227 const float zW(0.5
f * (zMinW + zMaxW));
229 const float dzU(zMaxU - zMinU);
230 const float dzV(zMaxV - zMinV);
231 const float dzW(zMaxW - zMinW);
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;
247 ++nMatchedSamplingPoints;
249 catch (StatusCodeException &statusCodeException)
251 if (statusCodeException.GetStatusCode() != STATUS_CODE_NOT_FOUND)
252 return statusCodeException.GetStatusCode();
259 if (nSamplingPoints == 0)
260 return STATUS_CODE_NOT_FOUND;
262 const float matchedFraction(static_cast<float>(nMatchedSamplingPoints) / static_cast<float>(nSamplingPoints));
265 return STATUS_CODE_NOT_FOUND;
267 xOverlapObject =
XOverlap(xMinU, xMaxU, xMinV, xMaxV, xMinW, xMaxW, xCentreOverlap);
269 return STATUS_CODE_SUCCESS;
274 template <
typename T>
276 const CaloHitList &pCluster1,
const CaloHitList &pCluster2,
const CaloHitList &pCluster3,
float &reducedChiSquared)
const 278 float chiSquaredSum(0.
f);
279 unsigned int nSamplingPoints(0), nMatchedSamplingPoints(0);
282 if (this->
PerformThreeViewMatching(pCluster1, pCluster2, pCluster3, chiSquaredSum, nSamplingPoints, nMatchedSamplingPoints,
283 xThreeViewOverlapObject) == STATUS_CODE_NOT_FOUND)
284 return STATUS_CODE_NOT_FOUND;
286 if (nSamplingPoints == 0)
287 return STATUS_CODE_NOT_FOUND;
289 reducedChiSquared = chiSquaredSum / nSamplingPoints;
291 return STATUS_CODE_SUCCESS;
296 template <
typename T>
298 const CaloHitList &clusterW,
float &chiSquaredSum,
unsigned int &nSamplingPoints,
unsigned int &nMatchedSamplingPoints,
XOverlap &xOverlapObject)
const 311 const float xCentreOverlap(xMaxCentre - xMinCentre);
313 if (xCentreOverlap < std::numeric_limits<float>::epsilon())
314 return STATUS_CODE_NOT_FOUND;
319 const float xOverlap(xMax - xMin);
321 const HitType hitTypeU(clusterU.front()->GetHitType());
322 const HitType hitTypeV(clusterV.front()->GetHitType());
323 const HitType hitTypeW(clusterW.front()->GetHitType());
325 if (hitTypeU == hitTypeV || hitTypeU == hitTypeW || hitTypeV == hitTypeW)
326 return STATUS_CODE_FAILURE;
328 const unsigned int nPoints(1 + static_cast<unsigned int>(xOverlap / xPitch));
332 nMatchedSamplingPoints = 0;
334 for (
unsigned int n = 0;
n < nPoints; ++
n)
336 const float x(xMin + (xMax - xMin) * (static_cast<float>(
n) + 0.5
f) / static_cast<float>(nPoints));
337 const float xmin(x - xPitch);
338 const float xmax(x + xPitch);
342 float zMinU(0.
f), zMinV(0.
f), zMinW(0.
f), zMaxU(0.
f), zMaxV(0.
f), zMaxW(0.
f);
347 const float zU(0.5
f * (zMinU + zMaxU));
348 const float zV(0.5
f * (zMinV + zMaxV));
349 const float zW(0.5
f * (zMinW + zMaxW));
351 const float dzU(zMaxU - zMinU);
352 const float dzV(zMaxV - zMinV);
353 const float dzW(zMaxW - zMinW);
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);
366 chiSquaredSum += pseudoChi2;
369 ++nMatchedSamplingPoints;
371 catch (StatusCodeException &statusCodeException)
373 if (statusCodeException.GetStatusCode() != STATUS_CODE_NOT_FOUND)
374 return statusCodeException.GetStatusCode();
381 if (nSamplingPoints == 0)
382 return STATUS_CODE_NOT_FOUND;
384 const float matchedFraction(static_cast<float>(nMatchedSamplingPoints) / static_cast<float>(nSamplingPoints));
387 return STATUS_CODE_NOT_FOUND;
389 xOverlapObject =
XOverlap(xMinU, xMaxU, xMinV, xMaxV, xMinW, xMaxW, xCentreOverlap);
391 return STATUS_CODE_SUCCESS;
396 template <
typename T>
402 for (
const CaloHit *
const pCaloHit : caloHitList)
404 const float xCoordinate(pCaloHit->GetPositionVector().GetX());
406 if (xCoordinate < xMin)
409 if (xCoordinate > xMax)
416 template <
typename T>
418 const CaloHitList &caloHitList,
const float xMin,
const float xMax,
float &zMin,
float &zMax)
const 424 for (
const CaloHit *
const pCaloHit : caloHitList)
426 const float xCoordinate(pCaloHit->GetPositionVector().GetX());
427 const float zCoordinate(pCaloHit->GetPositionVector().GetZ());
429 if ((xCoordinate < xMin) || (xCoordinate > xMax))
434 if (zCoordinate < zMin)
437 if (zCoordinate > zMax)
442 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
444 return STATUS_CODE_SUCCESS;
449 template <
typename T>
451 const HitType &thirdViewHitType,
const ParticleFlowObject *
const pParentMuon, CartesianPointVector &projectedPositions)
const 453 ClusterList muonClusterList1, muonClusterList2;
455 HitTypeVector hitTypes({TPC_VIEW_U, TPC_VIEW_V, TPC_VIEW_W});
457 hitTypes.erase(std::find(hitTypes.begin(), hitTypes.end(), thirdViewHitType));
462 if ((muonClusterList1.size() != 1) || (muonClusterList2.size() != 1))
463 return STATUS_CODE_NOT_FOUND;
465 return (this->
GetProjectedPositions(muonClusterList1.front(), muonClusterList2.front(), projectedPositions));
470 template <
typename T>
472 const Cluster *
const pCluster1,
const Cluster *
const pCluster2, CartesianPointVector &projectedPositions)
const 474 float xMin1(0.
f), xMax1(0.
f), xMin2(0.
f), xMax2(0.
f);
475 pCluster1->GetClusterSpanX(xMin1, xMax1);
476 pCluster2->GetClusterSpanX(xMin2, xMax2);
479 const float xMin(
std::max(xMin1, xMin2) - xPitch);
480 const float xMax(
std::min(xMax1, xMax2) + xPitch);
481 const float xOverlap(xMax - xMin);
483 if (xOverlap < std::numeric_limits<float>::epsilon())
484 return STATUS_CODE_NOT_FOUND;
489 if (hitType1 == hitType2)
490 throw StatusCodeException(STATUS_CODE_FAILURE);
492 const unsigned int nPoints(1 + static_cast<unsigned int>(xOverlap / xPitch));
495 for (
unsigned int n = 0;
n < nPoints; ++
n)
497 const float x(xMin + (xMax - xMin) * (static_cast<float>(
n) + 0.5
f) / static_cast<float>(nPoints));
498 const float xmin(x - xPitch);
499 const float xmax(x + xPitch);
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);
507 const float z1(0.5
f * (zMin1 + zMax1));
508 const float z2(0.5
f * (zMin2 + zMax2));
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);
515 projectedPositions.push_back(projection);
517 catch (StatusCodeException &statusCodeException)
519 if (statusCodeException.GetStatusCode() != STATUS_CODE_NOT_FOUND)
520 throw statusCodeException.GetStatusCode();
528 return STATUS_CODE_NOT_FOUND;
530 return STATUS_CODE_SUCCESS;
535 template <
typename T>
537 const Cluster *
const pThirdViewCluster,
const ParticleFlowObject *
const pParentMuon,
const float minDistanceFromMuon,
538 const float maxDistanceToCollected, CaloHitList &collectedHits)
const 540 HitType thirdViewHitType(TPC_VIEW_U);
541 CartesianPointVector deltaRayProjectedPositions;
543 if (!pThirdViewCluster)
545 if (this->
GetProjectedPositions(pCluster1, pCluster2, deltaRayProjectedPositions) != STATUS_CODE_SUCCESS)
546 return STATUS_CODE_NOT_FOUND;
548 for (
const HitType hitType : {TPC_VIEW_U, TPC_VIEW_V, TPC_VIEW_W})
552 thirdViewHitType = hitType;
559 CaloHitList deltaRayCaloHitList;
560 pThirdViewCluster->GetOrderedCaloHitList().FillCaloHitList(deltaRayCaloHitList);
562 for (
const CaloHit *
const pCaloHit : deltaRayCaloHitList)
563 deltaRayProjectedPositions.push_back(pCaloHit->GetPositionVector());
568 ClusterList muonClusterList;
571 if (muonClusterList.size() != 1)
572 return STATUS_CODE_NOT_FOUND;
574 const Cluster *
const pMuonCluster(muonClusterList.front());
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;
582 positionOnMuon, muonDirection, pMuonCluster, deltaRayProjectedPositions, minDistanceFromMuon, maxDistanceToCollected, collectedHits);
584 if (collectedHits.empty())
585 return STATUS_CODE_NOT_FOUND;
589 return STATUS_CODE_NOT_FOUND;
591 return STATUS_CODE_SUCCESS;
596 template <
typename T>
598 const Cluster *
const pMuonCluster,
const CartesianPointVector &deltaRayProjectedPositions,
const float &minDistanceFromMuon,
599 const float maxDistanceToCollected, CaloHitList &collectedHits)
const 601 CaloHitList cosmicRayHitList;
602 pMuonCluster->GetOrderedCaloHitList().FillCaloHitList(cosmicRayHitList);
604 bool hitsAdded(
true);
609 for (
const CaloHit *
const pCaloHit : cosmicRayHitList)
611 if (std::find(collectedHits.begin(), collectedHits.end(), pCaloHit) != collectedHits.end())
617 const float distanceToMuonHits(muonDirection.GetCrossProduct(pCaloHit->GetPositionVector() - positionOnMuon).GetMagnitude());
619 if ((std::fabs(distanceToMuonHits - distanceToCollectedHits) < std::numeric_limits<float>::epsilon()) ||
620 (distanceToMuonHits < minDistanceFromMuon) || (distanceToCollectedHits > distanceToMuonHits) ||
621 (distanceToCollectedHits > maxDistanceToCollected))
626 collectedHits.push_back(pCaloHit);
634 template <
typename T>
636 const Cluster *
const pDeltaRayCluster, CartesianVector &positionOnMuon, CartesianVector &muonDirection)
const 638 CaloHitList deltaRayHitList;
639 pDeltaRayCluster->GetOrderedCaloHitList().FillCaloHitList(deltaRayHitList);
641 CartesianPointVector deltaRayProjectedPositions;
643 for (
const CaloHit *
const pCaloHit : deltaRayHitList)
644 deltaRayProjectedPositions.push_back(pCaloHit->GetPositionVector());
652 template <
typename T>
654 const CartesianPointVector &deltaRayProjectedPositions,
const HitType hitType, CartesianVector &positionOnMuon, CartesianVector &muonDirection)
const 656 ClusterList muonClusterList;
659 if (muonClusterList.size() != 1)
660 return STATUS_CODE_NOT_FOUND;
662 CartesianPointVector muonProjectedPositions;
663 if (this->
ProjectMuonPositions(hitType, pParentMuon, muonProjectedPositions) != STATUS_CODE_SUCCESS)
664 return STATUS_CODE_NOT_FOUND;
666 const Cluster *
const pMuonCluster(muonClusterList.front());
670 CartesianVector deltaRayVertex(0.
f, 0.
f, 0.
f), muonVertex(0.
f, 0.
f, 0.
f);
676 if (status != STATUS_CODE_SUCCESS)
677 return STATUS_CODE_NOT_FOUND;
679 float rL(0.
f), rT(0.
f);
683 return STATUS_CODE_NOT_FOUND;
685 return STATUS_CODE_SUCCESS;
690 template <
typename T>
692 const CaloHitList &collectedHits,
const Cluster *&pDeltaRayCluster)
const 694 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Cluster>(*
this, clusterListName));
696 CaloHitList muonCaloHitList;
697 pMuonCluster->GetOrderedCaloHitList().FillCaloHitList(muonCaloHitList);
699 for (
const CaloHit *
const pCaloHit : muonCaloHitList)
701 if (std::find(collectedHits.begin(), collectedHits.end(), pCaloHit) != collectedHits.end())
703 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::RemoveFromCluster(*
this, pMuonCluster, pCaloHit));
705 if (!pDeltaRayCluster)
707 const ClusterList *pTemporaryList(
nullptr);
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));
713 PandoraContentApi::Cluster::Parameters parameters;
714 parameters.m_caloHitList.push_back(pCaloHit);
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));
722 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToCluster(*
this, pDeltaRayCluster, pCaloHit));
730 template <
typename T>
734 unsigned int aHitTotal(0);
736 aHitTotal += pCluster->GetNCaloHits();
738 unsigned int bHitTotal(0);
739 for (
const Cluster *
const pCluster :
b.m_clusterList)
740 bHitTotal += pCluster->GetNCaloHits();
742 return (aHitTotal > bHitTotal);
749 for (
const Cluster *
const pCluster : protoParticle.m_clusterList)
751 float minX(0.
f), maxX(0.
f);
752 pCluster->GetClusterSpanX(minX, maxX);
754 const float span(maxX - minX);
756 if (span > longestSpan)
764 for (
const Cluster *
const pCluster : protoParticle.m_clusterList)
766 ClusterList collectedClusters;
769 if (!collectedClusters.empty())
779 template <
typename T>
781 const Cluster *
const pClusterToEnlarge,
const float rangeMinX,
const float rangeMaxX, ClusterList &collectedClusters)
788 if (clusterProximityIter == clusterProximityMap.end())
791 for (
const Cluster *
const pNearbyCluster : clusterProximityIter->second)
793 if (std::find(strayClusterList.begin(), strayClusterList.end(), pNearbyCluster) == strayClusterList.end())
797 pNearbyCluster->GetClusterSpanX(xMin, xMax);
799 if (!(((xMin > rangeMinX) && (xMin < rangeMaxX)) || ((xMax > rangeMinX) && (xMax < rangeMaxX))))
805 if (std::find(collectedClusters.begin(), collectedClusters.end(), pNearbyCluster) == collectedClusters.end())
806 collectedClusters.push_back(pNearbyCluster);
812 template <
typename T>
817 for (
const Cluster *
const pCollectedCluster : collectedClusters)
822 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
823 PandoraContentApi::MergeAndDeleteClusters(*
this, pClusterToEnlarge, pCollectedCluster, clusterListName, clusterListName));
831 template <
typename T>
838 if (strayClusterIter != strayClusterList.end())
839 strayClusterList.erase(strayClusterIter);
842 const bool isMuonCluster(clusterToPfoMap.find(pDeletedCluster) != clusterToPfoMap.end());
852 template <
typename T>
857 for (
unsigned int i = 0; i < newClusterVector.size(); i++)
859 const Cluster *
const pNewCluster(newClusterVector.at(i));
860 const ParticleFlowObject *
const pMuonPfo(pfoVector.at(i));
870 template <
typename T>
884 template <
typename T>
887 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"MuonPfoListName",
m_muonPfoListName));
889 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
892 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"PseudoChi2Cut",
m_pseudoChi2Cut));
894 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"OverlapWindow",
m_xOverlapWindow));
896 PANDORA_RETURN_RESULT_IF_AND_IF(
897 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinMatchedFraction",
m_minMatchedFraction));
899 PANDORA_RETURN_RESULT_IF_AND_IF(
900 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinMatchedPoints",
m_minMatchedPoints));
902 PANDORA_RETURN_RESULT_IF_AND_IF(
903 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinProjectedPositions",
m_minProjectedPositions));
905 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
908 PANDORA_RETURN_RESULT_IF_AND_IF(
909 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxDistanceToCluster",
m_maxDistanceToCluster));
911 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
914 PANDORA_RETURN_RESULT_IF_AND_IF(
915 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"StrayClusterSeparation",
m_strayClusterSeparation));
std::vector< pandora::HitType > HitTypeVector
span(IterB &&b, IterE &&e, Adaptor &&adaptor) -> span< decltype(adaptor(std::forward< IterB >(b))), decltype(adaptor(std::forward< IterE >(e))) >
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)
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
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.
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.
static int max(int a, int b)
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...
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
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.
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.