9 #include "Pandora/AlgorithmHeaders.h" 22 DeltaRayMergeTool::DeltaRayMergeTool() :
23 m_maxDRSeparationFromTrack(1.5
f),
24 m_maxClusterSeparation(3.
f),
25 m_maxVertexSeparation(10.
f),
26 m_maxGoodMatchReducedChiSquared(1.
f)
36 if (PandoraContentApi::GetSettings(*m_pParentAlgorithm)->ShouldDisplayAlgorithmInfo())
37 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() <<
std::endl;
46 bool mergeMade(
false), mergesMade(
false), finishedTwoViewMerges(
false);
55 ClusterSet usedKeyClusters;
56 for (
const Cluster *
const pKeyCluster : sortedKeyClusters)
58 if (usedKeyClusters.count(pKeyCluster))
64 for (
const TensorType::Element &element : elementList)
65 usedKeyClusters.insert(element.GetClusterU());
67 if (elementList.size() < 2)
77 finishedTwoViewMerges =
true;
95 for (
auto iter1 = elementList.begin(); iter1 != elementList.end(); ++iter1)
97 const TensorType::Element &element1(*iter1);
99 for (
auto iter2 = std::next(iter1); iter2 != elementList.end(); ++iter2)
101 const TensorType::Element &element2(*iter2);
103 for (
const HitType hitType1 : {TPC_VIEW_U, TPC_VIEW_V})
105 if ((element1.GetCluster(hitType1) == element2.GetCluster(hitType1)))
107 for (
const HitType hitType2 : {TPC_VIEW_V, TPC_VIEW_W})
109 if (hitType1 == hitType2)
112 if ((element1.GetCluster(hitType2) == element2.GetCluster(hitType2)))
114 const HitType mergeHitType(hitType1 == TPC_VIEW_U ? (hitType2 == TPC_VIEW_V ? TPC_VIEW_W : TPC_VIEW_V) : TPC_VIEW_U);
115 const Cluster *pClusterToEnlarge(element1.GetCluster(mergeHitType)), *pClusterToDelete(element2.GetCluster(mergeHitType));
122 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
123 PandoraContentApi::ReplaceCurrentList<Cluster>(
126 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
127 PandoraContentApi::MergeAndDeleteClusters(*
m_pParentAlgorithm, pClusterToEnlarge, pClusterToDelete));
147 const PfoList &commonMuonPfoList1(element1.GetOverlapResult().GetCommonMuonPfoList());
148 const PfoList &commonMuonPfoList2(element2.GetOverlapResult().GetCommonMuonPfoList());
151 PfoList commonMuonPfoList;
154 if (commonMuonPfoList.empty())
157 const Cluster *
const pCluster1(element1.GetCluster(mergeHitType)), *
const pCluster2(element2.GetCluster(mergeHitType));
159 PfoList connectedMuonPfoList1, connectedMuonPfoList2;
163 if (connectedMuonPfoList1.empty() || connectedMuonPfoList2.empty())
166 for (
const ParticleFlowObject *
const pConnectedMuon1 : connectedMuonPfoList1)
168 for (
const ParticleFlowObject *
const pConnectedMuon2 : connectedMuonPfoList2)
170 if ((pConnectedMuon1 == pConnectedMuon2) && (this->
IsHiddenByTrack(pConnectedMuon1, pCluster1, pCluster2)))
182 for (
const ParticleFlowObject *
const pCommonMuonPfo1 : commonMuonPfoList1)
184 for (
const ParticleFlowObject *
const pCommonMuonPfo2 : commonMuonPfoList2)
186 if (pCommonMuonPfo1 == pCommonMuonPfo2)
187 commonMuonPfoList.push_back(pCommonMuonPfo1);
196 for (
const ParticleFlowObject *
const pCommonMuonPfo : commonMuonPfoList)
198 if (this->
IsConnected(pDeltaRayCluster, pCommonMuonPfo))
199 connectedMuonPfoList.push_back(pCommonMuonPfo);
209 ClusterList muonClusterList;
212 if (muonClusterList.size() != 1)
233 CaloHitList vertices1, vertices2;
237 if (vertices1.empty() || vertices2.empty())
240 for (
const CaloHit *
const pCaloHit : vertices1)
257 ClusterList muonClusterList;
260 if (muonClusterList.size() != 1)
263 CaloHitList caloHitList;
264 muonClusterList.front()->GetOrderedCaloHitList().FillCaloHitList(caloHitList);
266 for (
const CaloHit *
const pCaloHit : caloHitList)
269 vertexList.push_back(pCaloHit);
277 for (
auto iter1 = elementList.begin(); iter1 != elementList.end(); ++iter1)
279 const TensorType::Element &element1(*iter1);
281 for (
auto iter2 = std::next(iter1); iter2 != elementList.end(); ++iter2)
283 const TensorType::Element &element2(*iter2);
285 for (
const HitType hitType : {TPC_VIEW_U, TPC_VIEW_V, TPC_VIEW_W})
287 if (element1.GetCluster(hitType) == element2.GetCluster(hitType))
289 const HitType mergeHitType1(hitType == TPC_VIEW_U ? TPC_VIEW_V : hitType == TPC_VIEW_V ? TPC_VIEW_W : TPC_VIEW_U);
290 const HitType mergeHitType2(mergeHitType1 == TPC_VIEW_U ? TPC_VIEW_V : mergeHitType1 == TPC_VIEW_V ? TPC_VIEW_W : TPC_VIEW_U);
292 const Cluster *pClusterToEnlarge1 = element1.GetCluster(mergeHitType1), *pClusterToDelete1 = element2.GetCluster(mergeHitType1);
293 const Cluster *pClusterToEnlarge2 = element1.GetCluster(mergeHitType2), *pClusterToDelete2 = element2.GetCluster(mergeHitType2);
295 if ((pClusterToEnlarge1 == pClusterToDelete1) || (pClusterToEnlarge2 == pClusterToDelete2))
304 CaloHitList caloHitList1, caloHitList2, caloHitList3;
305 pClusterToEnlarge1->GetOrderedCaloHitList().FillCaloHitList(caloHitList1);
306 pClusterToDelete1->GetOrderedCaloHitList().FillCaloHitList(caloHitList1);
307 pClusterToEnlarge2->GetOrderedCaloHitList().FillCaloHitList(caloHitList2);
308 pClusterToDelete2->GetOrderedCaloHitList().FillCaloHitList(caloHitList2);
309 element1.GetCluster(hitType)->GetOrderedCaloHitList().FillCaloHitList(caloHitList3);
314 if (
status == STATUS_CODE_NOT_FOUND)
322 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
325 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
326 PandoraContentApi::MergeAndDeleteClusters(*
m_pParentAlgorithm, pClusterToEnlarge1, pClusterToDelete1));
333 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
336 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
337 PandoraContentApi::MergeAndDeleteClusters(*
m_pParentAlgorithm, pClusterToEnlarge2, pClusterToDelete2));
355 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
358 PANDORA_RETURN_RESULT_IF_AND_IF(
359 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxClusterSeparation",
m_maxClusterSeparation));
361 PANDORA_RETURN_RESULT_IF_AND_IF(
362 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxVertexSeparation",
m_maxVertexSeparation));
364 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
367 return STATUS_CODE_SUCCESS;
float m_maxVertexSeparation
The maximum separation of the connection points of two delta ray clusters that are hidden by a CR tra...
float m_maxClusterSeparation
The maximum separation of two broken clusters that should be merged.
Header file for the pfo helper class.
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 GetConnectedElements(const pandora::Cluster *const pCluster, const bool ignoreUnavailable, ElementList &elementList) const
Get a list of elements connected to a specified cluster.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
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...
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
ThreeViewDeltaRayMatchingAlgorithm * m_pParentAlgorithm
Address of the parent matching algorithm.
void GetConnectedMuons(const pandora::Cluster *const pDeltaRayCluster, const pandora::PfoList &commonMuonPfoList, pandora::PfoList &connectedMuonPfoList) const
Return the list of muon pfos that a specified delta ray cluster is directly connected to...
void UpdateUponDeletion(const pandora::Cluster *const pDeletedCluster)
Update to reflect cluster deletion.
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...
bool IsHiddenByTrack(const pandora::ParticleFlowObject *const pMuonPfo, const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2) const
Determine whether two delta ray clusters are actually a single cluster that is hidden behind a cosmic...
bool MakeOneCommonViewMerges(const TensorType::ElementList &elementList) const
Search for two matches with a single common cluster and attempt to merge the clusters in the other tw...
std::vector< Element > ElementList
Header file for the cluster helper class.
Header file for the muon leading helper class.
void CombineCommonMuonPfoLists(const pandora::PfoList &commonMuonPfoList1, const pandora::PfoList &commonMuonPfoList2, pandora::PfoList &commonMuonPfoList) const
Create a list of the shared common muon pfos of two elements.
void FindVertices(const pandora::Pfo *const pCommonMuonPfo, const pandora::Cluster *const pCluster, pandora::CaloHitList &vertexList) const
Find all connection points of a delta ray cluster and a cosmic ray pfo.
ThreeViewDeltaRayMatchingAlgorithm class.
static int max(int a, int b)
void GetSortedKeyClusters(pandora::ClusterVector &sortedKeyClusters) const
Get a sorted vector of key clusters (U clusters with current implementation)
bool Run(ThreeViewDeltaRayMatchingAlgorithm *const pAlgorithm, TensorType &overlapTensor)
Run the algorithm tool.
float m_maxGoodMatchReducedChiSquared
The threshold reduced chi squared value for a potential two view merge to go ahead.
bool ExamineConnectedElements(TensorType &overlapTensor) const
Identify ambiguous matches (e.g. 3:2:1) and attempt to merge clusters together.
bool IsConnected(const pandora::Cluster *const pCluster, const pandora::Pfo *const pCommonMuonPfo) const
Determine whether a given cluster is connected to a cosmic ray pfo.
bool IsBrokenCluster(const pandora::Cluster *const pClusterToEnlarge, const pandora::Cluster *const pClusterToDelete) const
Determine whether two delta ray clusters have been split.
const std::string & GetClusterListName(const pandora::HitType hitType) const
Get the cluster list name corresponding to a specified hit type.
float m_maxDRSeparationFromTrack
The maximum distance of a connected delta ray from a cosmic ray track.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
bool MakeTwoCommonViewMerges(const TensorType::ElementList &elementList) const
Search for two matches with two common clusters and attempt to merge the clusters in the third view t...
QTextStream & endl(QTextStream &s)
bool AreAssociated(const TensorType::Element &element1, const TensorType::Element &element2, const pandora::HitType &mergeHitType) const
Determine, from a topological point of view, whether two delta ray clusters should be merged together...
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.