Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
TwoDSlidingFitMultiSplitAlgorithm.cc
Go to the documentation of this file.
1
10
13
15
16using namespace pandora;
17
18namespace lar_content
19{
20
21TwoDSlidingFitMultiSplitAlgorithm::TwoDSlidingFitMultiSplitAlgorithm() : m_slidingFitHalfWindow(15), m_inputClusterList("")
22{
23}
24
25//------------------------------------------------------------------------------------------------------------------------------------------
26
28{
29 std::string originalListName;
30 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentListName<Cluster>(*this, originalListName));
31
32 if (!m_inputClusterList.empty())
33 {
35
36 if (STATUS_CODE_NOT_FOUND == statusCode)
37 {
38 std::cout << "TwoDSlidingFitMultiSplitAlgorithm: cluster list not found " << m_inputClusterList << std::endl;
39 return STATUS_CODE_SUCCESS;
40 }
41
42 if (STATUS_CODE_SUCCESS != statusCode)
43 return statusCode;
44 }
45
46 const ClusterList *pClusterList = NULL;
47 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pClusterList));
48
49 // Get ordered list of candidate clusters
50 ClusterVector clusterVector;
51 this->GetListOfCleanClusters(pClusterList, clusterVector);
52
53 // Build a set of sliding fit results for clean clusters
54 TwoDSlidingFitResultMap slidingFitResultMap;
55 this->BuildSlidingFitResultMap(clusterVector, m_slidingFitHalfWindow, slidingFitResultMap);
56
57 // Find best split positions for each cluster
58 ClusterPositionMap clusterSplittingMap;
59 this->FindBestSplitPositions(slidingFitResultMap, clusterSplittingMap);
60
61 // Perform splits
62 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->SplitClusters(slidingFitResultMap, clusterSplittingMap));
63
64 if (!m_inputClusterList.empty())
65 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Cluster>(*this, originalListName));
66
67 return STATUS_CODE_SUCCESS;
68}
69
70//------------------------------------------------------------------------------------------------------------------------------------------
71
73 const ClusterVector &clusterVector, const unsigned int halfWindowLayers, TwoDSlidingFitResultMap &slidingFitResultMap) const
74{
75 const float slidingFitPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
76
77 for (ClusterVector::const_iterator iter = clusterVector.begin(), iterEnd = clusterVector.end(); iter != iterEnd; ++iter)
78 {
79 if (slidingFitResultMap.end() == slidingFitResultMap.find(*iter))
80 {
81 try
82 {
83 const TwoDSlidingFitResult slidingFitResult(*iter, halfWindowLayers, slidingFitPitch);
84
85 if (!slidingFitResultMap.insert(TwoDSlidingFitResultMap::value_type(*iter, slidingFitResult)).second)
86 throw StatusCodeException(STATUS_CODE_FAILURE);
87 }
88 catch (StatusCodeException &statusCodeException)
89 {
90 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
91 throw statusCodeException;
92 }
93 }
94 }
95}
96
97//------------------------------------------------------------------------------------------------------------------------------------------
98
100 const TwoDSlidingFitResultMap &slidingFitResultMap, const ClusterPositionMap &clusterSplittingMap) const
101{
102 ClusterList clusterList;
103 for (const auto &mapEntry : clusterSplittingMap)
104 clusterList.push_back(mapEntry.first);
105 clusterList.sort(LArClusterHelper::SortByNHits);
106
107 for (const Cluster *const pCluster : clusterList)
108 {
109 const CartesianPointVector &splitPositionVector(clusterSplittingMap.at(pCluster));
110
111 if (splitPositionVector.empty())
112 continue;
113
114 TwoDSlidingFitResultMap::const_iterator sIter = slidingFitResultMap.find(pCluster);
115 if (slidingFitResultMap.end() == sIter)
116 throw StatusCodeException(STATUS_CODE_FAILURE);
117
118 const TwoDSlidingFitResult &slidingFitResult = sIter->second;
119
120 StatusCode statusCode(this->SplitCluster(slidingFitResult, splitPositionVector));
121
122 if (STATUS_CODE_SUCCESS != statusCode)
123 return statusCode;
124 }
125
126 return STATUS_CODE_SUCCESS;
127}
128
129//------------------------------------------------------------------------------------------------------------------------------------------
130
132{
133 const Cluster *const pCluster = slidingFitResult.GetCluster();
134
135 // Get split positions for this cluster
136 FloatVector displacementVector;
137
138 for (CartesianPointVector::const_iterator pIter = splitPositionVector.begin(), pIterEnd = splitPositionVector.end(); pIter != pIterEnd; ++pIter)
139 {
140 const CartesianVector &splitPosition = *pIter;
141
142 float rL(0.f), rT(0.f);
143 slidingFitResult.GetLocalPosition(splitPosition, rL, rT);
144 displacementVector.push_back(rL);
145 }
146
147 const float bigL(2.f * slidingFitResult.GetL(slidingFitResult.GetMaxLayer()));
148 displacementVector.push_back(-bigL);
149 displacementVector.push_back(+bigL);
150
151 std::sort(displacementVector.begin(), displacementVector.end());
152
153 // Begin cluster fragmentation operations
154 const ClusterList clusterList(1, pCluster);
155 std::string clusterListToSave, clusterListToDelete;
156
158 STATUS_CODE_SUCCESS, !=, PandoraContentApi::InitializeFragmentation(*this, clusterList, clusterListToDelete, clusterListToSave));
159
160 CaloHitList oldCaloHitList;
161 pCluster->GetOrderedCaloHitList().FillCaloHitList(oldCaloHitList);
162
163 bool foundPreviousL(false);
164 float prevL(0.f);
165
166 for (FloatVector::const_iterator fIter = displacementVector.begin(), fIterEnd = displacementVector.end(); fIter != fIterEnd; ++fIter)
167 {
168 const float nextL(*fIter);
169
170 if (foundPreviousL)
171 {
172 // Select hits for new cluster
173 CaloHitList newCaloHitList;
174
175 for (CaloHitList::const_iterator hIter = oldCaloHitList.begin(), hIterEnd = oldCaloHitList.end(); hIter != hIterEnd; ++hIter)
176 {
177 const CaloHit *const pCaloHit = *hIter;
178
179 float rL(0.f), rT(0.f);
180 slidingFitResult.GetLocalPosition(pCaloHit->GetPositionVector(), rL, rT);
181
182 if (rL >= prevL && rL < nextL)
183 newCaloHitList.push_back(pCaloHit);
184 }
185
186 if (newCaloHitList.empty())
187 continue;
188
189 // Create new cluster
190 PandoraContentApi::Cluster::Parameters newParameters;
191 newParameters.m_caloHitList = newCaloHitList;
192
193 const Cluster *pNewCluster(NULL);
194 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::Create(*this, newParameters, pNewCluster));
195 }
196
197 prevL = nextL;
198 foundPreviousL = true;
199 }
200
201 // End cluster fragmentation operations
202 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::EndFragmentation(*this, clusterListToSave, clusterListToDelete));
203
204 return STATUS_CODE_SUCCESS;
205}
206
207//------------------------------------------------------------------------------------------------------------------------------------------
208
210{
212 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "InputClusterListName", m_inputClusterList));
213
215 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "SlidingFitHalfWindow", m_slidingFitHalfWindow));
216
217 return STATUS_CODE_SUCCESS;
218}
219
220} // namespace lar_content
Grouping of header files for many classes of use in particle flow algorithms.
Header file for the cluster helper class.
Header file for the geometry helper class.
#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 2D sliding fit multi-split algorithm 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 InitializeFragmentation(const pandora::Algorithm &algorithm, const pandora::ClusterList &inputClusterList, std::string &originalClustersListName, std::string &fragmentClustersListName)
Initialize cluster fragmentation operations on clusters in the algorithm input list....
static pandora::StatusCode EndFragmentation(const pandora::Algorithm &algorithm, const std::string &clusterListToSaveName, const std::string &clusterListToDeleteName)
End cluster fragmentation operations on clusters in the algorithm input list.
static pandora::StatusCode GetCurrentList(const pandora::Algorithm &algorithm, const T *&pT)
Get the current list.
static bool SortByNHits(const pandora::Cluster *const pLhs, const pandora::Cluster *const pRhs)
Sort clusters by number of hits, then layer span, then inner layer, then position,...
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
void BuildSlidingFitResultMap(const pandora::ClusterVector &clusterVector, const unsigned int halfWindowLayers, TwoDSlidingFitResultMap &slidingFitResultMap) const
Build the map of sliding fit results.
std::unordered_map< const pandora::Cluster *, pandora::CartesianPointVector > ClusterPositionMap
virtual void GetListOfCleanClusters(const pandora::ClusterList *const pClusterList, pandora::ClusterVector &clusterVector) const =0
Populate cluster vector with subset of cluster list, containing clusters judged to be clean.
pandora::StatusCode SplitCluster(const TwoDSlidingFitResult &slidingFitResult, const pandora::CartesianPointVector &splitPositionList) const
Split cluster.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
pandora::StatusCode SplitClusters(const TwoDSlidingFitResultMap &slidingFitResultMap, const ClusterPositionMap &clusterSplittingMap) const
Split clusters.
virtual void FindBestSplitPositions(const TwoDSlidingFitResultMap &slidingFitResultMap, ClusterPositionMap &clusterSplittingMap) const =0
Determine best split positions based on sliding fit result.
float GetL(const int layer) const
Get longitudinal coordinate for a given sliding linear fit layer number.
void GetLocalPosition(const pandora::CartesianVector &position, float &rL, float &rT) const
Get local sliding fit coordinates for a given global position.
int GetMaxLayer() const
Get the maximum occupied layer in the sliding fit.
const pandora::Cluster * GetCluster() const
Get the address of the cluster, if originally provided.
CaloHit class.
Definition CaloHit.h:26
const CartesianVector & GetPositionVector() const
Get the position vector of center of calorimeter cell, units mm.
Definition CaloHit.h:350
CartesianVector class.
Cluster class.
Definition Cluster.h:31
const OrderedCaloHitList & GetOrderedCaloHitList() const
Get the ordered calo hit list.
Definition Cluster.h:470
void FillCaloHitList(CaloHitList &caloHitList) const
Fill a provided calo hit list with all the calo hits in the ordered calo hit list.
const Pandora & GetPandora() const
Get the associated pandora instance.
Definition Process.h:116
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::unordered_map< const pandora::Cluster *, TwoDSlidingFitResult > TwoDSlidingFitResultMap
std::vector< const Cluster * > ClusterVector
MANAGED_CONTAINER< const Cluster * > ClusterList
std::vector< CartesianVector > CartesianPointVector
MANAGED_CONTAINER< const CaloHit * > CaloHitList
std::vector< float > FloatVector
StatusCode
The StatusCode enum.