LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
CheatingClusterMergingAlgorithm.cc
Go to the documentation of this file.
1 
9 #include "Helpers/MCParticleHelper.h"
10 #include "Objects/MCParticle.h"
11 #include "Pandora/AlgorithmHeaders.h"
12 
13 #include <cmath>
14 
20 
21 using namespace pandora;
22 
23 namespace lar_content
24 {
25 
26 CheatingClusterMergingAlgorithm::CheatingClusterMergingAlgorithm() :
27  m_minNCaloHits(1)
28 {
29 }
30 //------------------------------------------------------------------------------------------//
31 
33 {
34  for (const std::string &clusterListName : m_inputClusterListNames)
35  {
36  try
37  {
38  const ClusterList *pClusterList{nullptr};
39  PANDORA_RETURN_RESULT_IF_AND_IF(
40  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*this, clusterListName, pClusterList));
41 
42  if (!pClusterList || pClusterList->empty())
43  {
44  if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
45  std::cout << "ClusterMergingAlgorithm: unable to find cluster list " << clusterListName << std::endl;
46 
47  continue;
48  }
49  this->CheatedClusterMerging(pClusterList, clusterListName);
50  }
51  catch (StatusCodeException &statusCodeException)
52  {
53  throw statusCodeException;
54  }
55  }
56  return STATUS_CODE_SUCCESS;
57 }
58 //--------------------------------------------------------------------------------------------//
60  const Cluster *const cluster, std::map<const Cluster *, const MCParticle *> &clusterToMCMap) const
61 {
62  const MCParticle *clusterMC{nullptr};
63 
64  if (clusterToMCMap.count(cluster) > 0)
65  {
66  clusterMC = clusterToMCMap.at(cluster);
67  }
68  else
69  {
70  try
71  {
72  clusterMC = MCParticleHelper::GetMainMCParticle(cluster);
73  clusterToMCMap[cluster] = clusterMC;
74  }
75  catch (StatusCodeException e)
76  {
77  std::cout << "Failed to get MC particle for cluster of " << cluster->GetOrderedCaloHitList().size() << " : " << e.ToString() << std::endl;
78  }
79  }
80  return clusterMC;
81 }
82 
83 //---------------------------------------------------------------------------------------------//
84 
85 bool CheatingClusterMergingAlgorithm::IsValidToUse(const Cluster *const cluster, std::map<const Cluster *, bool> &clusterIsUsed) const
86 {
87  if (!cluster->IsAvailable())
88  return false;
89 
90  if (cluster->GetNCaloHits() < m_minNCaloHits)
91  return false;
92 
93  if (clusterIsUsed.count(cluster) > 0)
94  return false;
95 
96  return true;
97 }
98 
99 //-----------------------------------------------------------------------------------------------//
100 
101 void CheatingClusterMergingAlgorithm::CheatedClusterMerging(const pandora::ClusterList *const pClusterList, const std::string &listName) const
102 {
103  std::map<const Cluster *, const MCParticle *> clusterToMCParticleMap;
104  std::map<const Cluster *, bool> clusterIsUsed;
105  std::map<const Cluster *, ClusterVector> clustersToMerge;
106 
107  for (auto it = pClusterList->begin(); it != pClusterList->end(); ++it)
108  {
109  const Cluster *cluster(*it);
110 
111  if (!this->IsValidToUse(cluster, clusterIsUsed))
112  continue;
113 
114  const MCParticle *clusterMC(this->GetMCForCluster(cluster, clusterToMCParticleMap));
115 
116  for (auto it2 = std::next(it); it2 != pClusterList->end(); ++it2)
117  {
118  const Cluster *const otherCluster(*it2);
119 
120  if (!this->IsValidToUse(otherCluster, clusterIsUsed))
121  continue;
122 
123  const MCParticle *otherClusterMC(this->GetMCForCluster(otherCluster, clusterToMCParticleMap));
124 
125  if (clusterMC == otherClusterMC)
126  {
127  clusterIsUsed[cluster] = true;
128  clusterIsUsed[otherCluster] = true;
129  clustersToMerge[cluster].emplace_back(otherCluster);
130  }
131  }
132  }
133 
134  for (auto clusterToMergePair : clustersToMerge)
135  {
136  const Cluster *currentCluster{clusterToMergePair.first};
137  const auto clusters{clusterToMergePair.second};
138 
139  for (auto clusterToMerge : clusters)
140  {
141  if (!clusterToMerge->IsAvailable())
142  continue;
143 
144  try
145  {
146  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
147  PandoraContentApi::MergeAndDeleteClusters(*this, currentCluster, clusterToMerge, listName, listName));
148  }
149  catch (StatusCodeException)
150  {
151  }
152  }
153  }
154 }
155 
156 //-------------------------------------------------------------------------------------------------
157 
158 StatusCode CheatingClusterMergingAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
159 {
160  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadVectorOfValues(xmlHandle, "InputClusterListNames", m_inputClusterListNames));
161 
162  PANDORA_RETURN_RESULT_IF_AND_IF(
163  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MCParticleListName", m_mcParticleListName));
164 
165  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinNCaloHits", m_minNCaloHits));
166 
167  return STATUS_CODE_SUCCESS;
168 }
169 
170 } // namespace lar_content
Header file for the cheating cluster merging algorithm.
pandora::StringVector m_inputClusterListNames
The names of the input cluster lists.
std::string m_mcParticleListName
Input MC particle list name.
void CheatedClusterMerging(const pandora::ClusterList *const pClusterList, const std::string &listName) const
Cheated Cluster Merging. Use MC to match clusters based on the main MC particle.
Cluster finding and building.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Header file for the lar monte carlo particle helper helper class.
Header file for the cluster helper class.
Header file for the lar mc particle class.
Header file for the shower growing algorithm class.
bool IsValidToUse(const pandora::Cluster *const cluster, std::map< const pandora::Cluster *, bool > &clusterIsUsed) const
If a cluster is valid to use: Is a shower tagged cluster, and not been used yet.
Float_t e
Definition: plot.C:35
const pandora::MCParticle * GetMCForCluster(const pandora::Cluster *const cluster, std::map< const pandora::Cluster *, const pandora::MCParticle * > &clusterToMCMap) const
Get the MC particle for a given cluster, caching to a map.
float m_minNCaloHits
The minimum number of hits for a cluster to be deemed true for IsAvailableToUse.