Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
ThreeDKinkBaseTool.cc
Go to the documentation of this file.
1
10
12
14
16
17using namespace pandora;
18
19namespace lar_content
20{
21
22ThreeDKinkBaseTool::ThreeDKinkBaseTool(const unsigned int nCommonClusters) :
23 m_nCommonClusters(nCommonClusters),
24 m_majorityRulesMode(false),
25 m_minMatchedFraction(0.75f),
26 m_minMatchedSamplingPoints(10),
27 m_minLongitudinalImpactParameter(-1.f),
28 m_nLayersForKinkSearch(10),
29 m_additionalXStepForKinkSearch(0.01f)
30{
31 if (!((1 == m_nCommonClusters) || (2 == m_nCommonClusters)))
32 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
33}
34
35//------------------------------------------------------------------------------------------------------------------------------------------
36
40
41//------------------------------------------------------------------------------------------------------------------------------------------
42
43bool ThreeDKinkBaseTool::PassesElementCuts(TensorType::ElementList::const_iterator eIter, const ClusterSet &usedClusters) const
44{
45 if (usedClusters.count(eIter->GetClusterU()) || usedClusters.count(eIter->GetClusterV()) || usedClusters.count(eIter->GetClusterW()))
46 return false;
47
48 if (eIter->GetOverlapResult().GetMatchedFraction() < m_minMatchedFraction)
49 return false;
50
51 if (eIter->GetOverlapResult().GetNMatchedSamplingPoints() < m_minMatchedSamplingPoints)
52 return false;
53
54 return true;
55}
56
57//------------------------------------------------------------------------------------------------------------------------------------------
58
59float ThreeDKinkBaseTool::GetXSamplingPoint(const CartesianVector &splitPosition1, const bool isForwardInX,
60 const TwoDSlidingFitResult &fitResult1, const TwoDSlidingFitResult &fitResult2, const TwoDSlidingFitResult &fitResult3) const
61{
62 // Nearest common x position
63 float xMin1(std::numeric_limits<float>::max()), xMax1(-std::numeric_limits<float>::max());
64 float xMin2(std::numeric_limits<float>::max()), xMax2(-std::numeric_limits<float>::max());
65 float xMin3(std::numeric_limits<float>::max()), xMax3(-std::numeric_limits<float>::max());
66 fitResult1.GetMinAndMaxX(xMin1, xMax1);
67 fitResult2.GetMinAndMaxX(xMin2, xMax2);
68 fitResult3.GetMinAndMaxX(xMin3, xMax3);
69
70 const float commonX(isForwardInX ? std::max(xMin1, std::max(xMin2, xMin3)) : std::min(xMax1, std::min(xMax2, xMax3)));
71
72 if (isForwardInX && ((commonX > xMax1) || (commonX > xMax2) || (commonX > xMax3)))
73 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
74
75 if (!isForwardInX && ((commonX < xMin1) || (commonX < xMin2) || (commonX < xMin3)))
76 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
77
78 // Layer step x position
79 float rL1(0.f), rT1(0.f);
80 fitResult1.GetLocalPosition(splitPosition1, rL1, rT1);
81 const int splitLayer(fitResult1.GetLayer(rL1));
82
83 const int lowLayer(std::max(fitResult1.GetMinLayer(), std::min(fitResult1.GetMaxLayer(), splitLayer - m_nLayersForKinkSearch)));
84 const int highLayer(std::max(fitResult1.GetMinLayer(), std::min(fitResult1.GetMaxLayer(), splitLayer + m_nLayersForKinkSearch)));
85
86 CartesianVector minus(0.f, 0.f, 0.f), plus(0.f, 0.f, 0.f);
87 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, fitResult1.GetGlobalFitPosition(fitResult1.GetL(lowLayer), minus));
88 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, fitResult1.GetGlobalFitPosition(fitResult1.GetL(highLayer), plus));
89
90 if (minus.GetX() > plus.GetX())
91 {
92 CartesianVector temporary(minus);
93 minus = plus;
94 plus = temporary;
95 }
96
97 const float layerStepX(isForwardInX ? plus.GetX() : minus.GetX());
98
99 // Final x position selection
100 const float chosenX(isForwardInX ? std::max(layerStepX, commonX) : std::min(layerStepX, commonX));
101 const float finalX(isForwardInX ? chosenX + m_additionalXStepForKinkSearch : chosenX - m_additionalXStepForKinkSearch);
102 return finalX;
103}
104
105//------------------------------------------------------------------------------------------------------------------------------------------
106
107bool ThreeDKinkBaseTool::IsALowestInX(const LArPointingCluster &pointingClusterA, const LArPointingCluster &pointingClusterB)
108{
109 if ((pointingClusterA.GetInnerVertex().GetPosition().GetX() < pointingClusterB.GetInnerVertex().GetPosition().GetX()) &&
110 (pointingClusterA.GetInnerVertex().GetPosition().GetX() < pointingClusterB.GetOuterVertex().GetPosition().GetX()))
111 {
112 return true;
113 }
114
115 if ((pointingClusterA.GetOuterVertex().GetPosition().GetX() < pointingClusterB.GetInnerVertex().GetPosition().GetX()) &&
116 (pointingClusterA.GetOuterVertex().GetPosition().GetX() < pointingClusterB.GetOuterVertex().GetPosition().GetX()))
117 {
118 return true;
119 }
120
121 return false;
122}
123
124//------------------------------------------------------------------------------------------------------------------------------------------
125
127{
129 std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
130
131 ModificationList modificationList;
132 this->GetModifications(pAlgorithm, overlapTensor, modificationList);
133 const bool changesMade(this->ApplyChanges(pAlgorithm, modificationList));
134
135 return changesMade;
136}
137
138//------------------------------------------------------------------------------------------------------------------------------------------
139
141 ThreeViewTransverseTracksAlgorithm *const pAlgorithm, const TensorType &overlapTensor, ModificationList &modificationList) const
142{
143 ClusterSet usedClusters;
144 ClusterVector sortedKeyClusters;
145 overlapTensor.GetSortedKeyClusters(sortedKeyClusters);
146
147 for (const Cluster *const pKeyCluster : sortedKeyClusters)
148 {
149 if (!pKeyCluster->IsAvailable())
150 continue;
151
152 unsigned int nU(0), nV(0), nW(0);
153 TensorType::ElementList elementList;
154 overlapTensor.GetConnectedElements(pKeyCluster, true, elementList, nU, nV, nW);
155
156 if (nU * nV * nW < 2)
157 continue;
158
159 for (TensorType::ElementList::const_iterator eIter = elementList.begin(); eIter != elementList.end(); ++eIter)
160 {
161 if (!this->PassesElementCuts(eIter, usedClusters))
162 continue;
163
164 IteratorList iteratorList;
165 this->SelectTensorElements(eIter, elementList, usedClusters, iteratorList);
166
167 if (iteratorList.size() < 2)
168 continue;
169
170 ModificationList localModificationList;
171 this->GetIteratorListModifications(pAlgorithm, iteratorList, localModificationList);
172
173 if (localModificationList.empty())
174 continue;
175
176 for (ModificationList::const_iterator mIter = localModificationList.begin(), mIterEnd = localModificationList.end(); mIter != mIterEnd; ++mIter)
177 {
178 usedClusters.insert(mIter->m_affectedClusters.begin(), mIter->m_affectedClusters.end());
179 }
180
181 modificationList.insert(modificationList.end(), localModificationList.begin(), localModificationList.end());
182 }
183 }
184}
185
186//------------------------------------------------------------------------------------------------------------------------------------------
187
189{
190 ClusterMergeMap consolidatedMergeMap;
191 SplitPositionMap consolidatedSplitMap;
192
193 for (const Modification &modification : modificationList)
194 {
195 ClusterList parentClusters;
196 for (const auto &mapEntry : modification.m_clusterMergeMap)
197 parentClusters.push_back(mapEntry.first);
198 parentClusters.sort(LArClusterHelper::SortByNHits);
199
200 for (const Cluster *const pParentCluster : parentClusters)
201 {
202 const ClusterList &daughterClusters(modification.m_clusterMergeMap.at(pParentCluster));
203
204 for (const Cluster *const pDaughterCluster : daughterClusters)
205 {
206 if (consolidatedMergeMap.count(pDaughterCluster))
207 throw StatusCodeException(STATUS_CODE_FAILURE);
208 }
209
210 ClusterList &targetClusterList(consolidatedMergeMap[pParentCluster]);
211 targetClusterList.insert(targetClusterList.end(), daughterClusters.begin(), daughterClusters.end());
212 }
213
214 ClusterList splitClusters;
215 for (const auto &mapEntry : modification.m_splitPositionMap)
216 splitClusters.push_back(mapEntry.first);
217 splitClusters.sort(LArClusterHelper::SortByNHits);
218
219 for (const Cluster *const pSplitCluster : splitClusters)
220 {
221 const CartesianPointVector &splitPositions(modification.m_splitPositionMap.at(pSplitCluster));
222
223 CartesianPointVector &cartesianPointVector(consolidatedSplitMap[pSplitCluster]);
224 cartesianPointVector.insert(cartesianPointVector.end(), splitPositions.begin(), splitPositions.end());
225 }
226 }
227
228 bool changesMade(false);
229 changesMade |= pAlgorithm->MakeClusterMerges(consolidatedMergeMap);
230 changesMade |= pAlgorithm->MakeClusterSplits(consolidatedSplitMap);
231
232 return changesMade;
233}
234
235//------------------------------------------------------------------------------------------------------------------------------------------
236
237void ThreeDKinkBaseTool::SelectTensorElements(TensorType::ElementList::const_iterator eIter, const TensorType::ElementList &elementList,
238 const ClusterSet &usedClusters, IteratorList &iteratorList) const
239{
240 iteratorList.push_back(eIter);
241
242 for (TensorType::ElementList::const_iterator eIter2 = elementList.begin(); eIter2 != elementList.end(); ++eIter2)
243 {
244 if (eIter == eIter2)
245 continue;
246
247 if (!this->PassesElementCuts(eIter2, usedClusters))
248 continue;
249
250 for (IteratorList::const_iterator iIter = iteratorList.begin(); iIter != iteratorList.end(); ++iIter)
251 {
252 if ((*iIter) == eIter2)
253 continue;
254
255 unsigned int nMatchedClusters(0);
256
257 if ((*iIter)->GetClusterU() == eIter2->GetClusterU())
258 ++nMatchedClusters;
259
260 if ((*iIter)->GetClusterV() == eIter2->GetClusterV())
261 ++nMatchedClusters;
262
263 if ((*iIter)->GetClusterW() == eIter2->GetClusterW())
264 ++nMatchedClusters;
265
266 if (m_nCommonClusters == nMatchedClusters)
267 {
268 iteratorList.push_back(eIter2);
269 return;
270 }
271 }
272 }
273}
274
275//------------------------------------------------------------------------------------------------------------------------------------------
276
278{
280 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MajorityRulesMode", m_majorityRulesMode));
281
283 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinMatchedFraction", m_minMatchedFraction));
284
285 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
286 XmlHelper::ReadValue(xmlHandle, "MinMatchedSamplingPoints", m_minMatchedSamplingPoints));
287
288 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
289 XmlHelper::ReadValue(xmlHandle, "MinLongitudinalImpactParameter", m_minLongitudinalImpactParameter));
290
292 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "NLayersForKinkSearch", m_nLayersForKinkSearch));
293
294 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
295 XmlHelper::ReadValue(xmlHandle, "AdditionalXStepForKinkSearch", m_additionalXStepForKinkSearch));
296
297 return STATUS_CODE_SUCCESS;
298}
299
300} // 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 lar pointing cluster class.
#define PANDORA_THROW_RESULT_IF(StatusCode1, Operator, Command)
Definition StatusCodes.h:43
#define PANDORA_RETURN_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
Definition StatusCodes.h:31
Header file for the three d kink base tool.
static const pandora::PandoraSettings * GetSettings(const pandora::Algorithm &algorithm)
Get the pandora settings instance.
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,...
const pandora::CartesianVector & GetPosition() const
Get the vertex position.
LArPointingCluster class.
const Vertex & GetInnerVertex() const
Get the inner vertex.
const Vertex & GetOuterVertex() const
Get the outer vertex.
virtual bool MakeClusterMerges(const ClusterMergeMap &clusterMergeMap)
Merge clusters together.
virtual bool MakeClusterSplits(const SplitPositionMap &splitPositionMap)
Make cluster splits.
virtual ~ThreeDKinkBaseTool()
Destructor.
void GetModifications(ThreeViewTransverseTracksAlgorithm *const pAlgorithm, const TensorType &overlapTensor, ModificationList &modificationList) const
Get modification objects, identifying required splits and merges for clusters.
static bool IsALowestInX(const LArPointingCluster &pointingClusterA, const LArPointingCluster &pointingClusterB)
Whether pointing cluster labelled A extends to lowest x positions (as opposed to that labelled B)
float GetXSamplingPoint(const pandora::CartesianVector &splitPosition1, const bool isForwardInX, const TwoDSlidingFitResult &fitResult1, const TwoDSlidingFitResult &fitResult2, const TwoDSlidingFitResult &fitResult3) const
Get a sampling point in x that is common to sliding linear fit objects in three views.
float m_minMatchedFraction
The min matched sampling point fraction for use as a key tensor element.
bool Run(ThreeViewTransverseTracksAlgorithm *const pAlgorithm, TensorType &overlapTensor)
Run the algorithm tool.
void SelectTensorElements(TensorType::ElementList::const_iterator eIter, const TensorType::ElementList &elementList, const pandora::ClusterSet &usedClusters, IteratorList &iteratorList) const
Select elements representing possible components of interest due to overshoots or undershoots in clus...
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
virtual bool PassesElementCuts(TensorType::ElementList::const_iterator eIter, const pandora::ClusterSet &usedClusters) const
Whether a provided (iterator to a) tensor element passes the selection cuts for overshoot identificat...
virtual void GetIteratorListModifications(ThreeViewTransverseTracksAlgorithm *const pAlgorithm, const IteratorList &iteratorList, ModificationList &modificationList) const =0
Get modification objects for a specific elements of the tensor, identifying required splits and merge...
unsigned int m_nCommonClusters
The number of common clusters.
bool ApplyChanges(ThreeViewTransverseTracksAlgorithm *const pAlgorithm, const ModificationList &modificationList) const
Apply the changes cached in a modification list and update the tensor accordingly.
ThreeDKinkBaseTool(const unsigned int nCommonClusters)
Constructor.
float m_additionalXStepForKinkSearch
An additional (safety) step to tack-on when choosing x sampling points.
float m_minLongitudinalImpactParameter
The min longitudinal impact parameter for connecting accompanying clusters.
int m_nLayersForKinkSearch
The number of sliding fit layers to step in the kink search.
unsigned int m_minMatchedSamplingPoints
The min number of matched sampling points for use as a key tensor element.
bool m_majorityRulesMode
Whether to run in majority rules mode (always split overshoots, always merge undershoots)
std::vector< Modification > ModificationList
ThreeViewTransverseTracksAlgorithm::MatchingType::TensorType TensorType
std::vector< TensorType::ElementList::const_iterator > IteratorList
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.
pandora::StatusCode GetGlobalFitPosition(const float rL, pandora::CartesianVector &position) const
Get global fit position for a given longitudinal coordinate.
int GetMaxLayer() const
Get the maximum occupied layer in the sliding fit.
int GetMinLayer() const
Get the minimum occupied layer in the sliding fit.
int GetLayer(const float rL) const
Get layer number for given sliding linear fit longitudinal coordinate.
void GetMinAndMaxX(float &minX, float &maxX) const
Get the minimum and maximum x coordinates associated with the sliding fit.
CartesianVector class.
float GetX() const
Get the cartesian x coordinate.
Cluster class.
Definition Cluster.h:31
bool ShouldDisplayAlgorithmInfo() const
Whether to display algorithm information during processing.
const std::string & GetType() const
Get the type.
Definition Process.h:102
const std::string & GetInstanceName() const
Get the instance name.
Definition Process.h:109
StatusCodeException class.
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 *, pandora::ClusterList > ClusterMergeMap
std::unordered_map< const pandora::Cluster *, pandora::CartesianPointVector > SplitPositionMap
std::vector< const Cluster * > ClusterVector
MANAGED_CONTAINER< const Cluster * > ClusterList
std::vector< CartesianVector > CartesianPointVector
std::unordered_set< const Cluster * > ClusterSet
StatusCode
The StatusCode enum.