Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
ThreeViewTransverseTracksAlgorithm.cc
Go to the documentation of this file.
1
10
13
15
16using namespace pandora;
17
18namespace lar_content
19{
20
22 m_nMaxTensorToolRepeats(1000),
23 m_maxFitSegmentIndex(50),
24 m_pseudoChi2Cut(3.f),
25 m_minSegmentMatchedFraction(0.1f),
26 m_minSegmentMatchedPoints(3),
27 m_minOverallMatchedFraction(0.5f),
28 m_minOverallMatchedPoints(10),
29 m_minSamplingPointsPerLayer(0.1f)
30{
31}
32
33//------------------------------------------------------------------------------------------------------------------------------------------
34
35void ThreeViewTransverseTracksAlgorithm::CalculateOverlapResult(const Cluster *const pClusterU, const Cluster *const pClusterV, const Cluster *const pClusterW)
36{
37 TransverseOverlapResult overlapResult;
39 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, this->CalculateOverlapResult(pClusterU, pClusterV, pClusterW, overlapResult));
40
41 if (overlapResult.IsInitialized())
42 this->GetMatchingControl().GetOverlapTensor().SetOverlapResult(pClusterU, pClusterV, pClusterW, overlapResult);
43}
44
45//------------------------------------------------------------------------------------------------------------------------------------------
46
48 const Cluster *const pClusterU, const Cluster *const pClusterV, const Cluster *const pClusterW, TransverseOverlapResult &overlapResult)
49{
50 const TwoDSlidingFitResult &slidingFitResultU(this->GetCachedSlidingFitResult(pClusterU));
51 const TwoDSlidingFitResult &slidingFitResultV(this->GetCachedSlidingFitResult(pClusterV));
52 const TwoDSlidingFitResult &slidingFitResultW(this->GetCachedSlidingFitResult(pClusterW));
53
54 FitSegmentTensor fitSegmentTensor;
55 this->GetFitSegmentTensor(slidingFitResultU, slidingFitResultV, slidingFitResultW, fitSegmentTensor);
56
57 TransverseOverlapResult transverseOverlapResult;
58 this->GetBestOverlapResult(fitSegmentTensor, transverseOverlapResult);
59
60 if (!transverseOverlapResult.IsInitialized())
61 return STATUS_CODE_NOT_FOUND;
62
63 if ((transverseOverlapResult.GetMatchedFraction() < m_minOverallMatchedFraction) ||
64 (transverseOverlapResult.GetNMatchedSamplingPoints() < m_minOverallMatchedPoints))
65 return STATUS_CODE_NOT_FOUND;
66
67 const int nLayersSpannedU(slidingFitResultU.GetMaxLayer() - slidingFitResultU.GetMinLayer());
68 const int nLayersSpannedV(slidingFitResultV.GetMaxLayer() - slidingFitResultV.GetMinLayer());
69 const int nLayersSpannedW(slidingFitResultW.GetMaxLayer() - slidingFitResultW.GetMinLayer());
70 const unsigned int meanLayersSpanned(
71 static_cast<unsigned int>((1.f / 3.f) * static_cast<float>(nLayersSpannedU + nLayersSpannedV + nLayersSpannedW)));
72
73 if (0 == meanLayersSpanned)
74 return STATUS_CODE_FAILURE;
75
76 const float nSamplingPointsPerLayer(static_cast<float>(transverseOverlapResult.GetNSamplingPoints()) / static_cast<float>(meanLayersSpanned));
77
78 if (nSamplingPointsPerLayer < m_minSamplingPointsPerLayer)
79 return STATUS_CODE_NOT_FOUND;
80
81 overlapResult = transverseOverlapResult;
82 return STATUS_CODE_SUCCESS;
83}
84
85//------------------------------------------------------------------------------------------------------------------------------------------
86
88 const TwoDSlidingFitResult &slidingFitResultV, const TwoDSlidingFitResult &slidingFitResultW, FitSegmentTensor &fitSegmentTensor) const
89{
90 FitSegmentList fitSegmentListU(slidingFitResultU.GetFitSegmentList());
91 FitSegmentList fitSegmentListV(slidingFitResultV.GetFitSegmentList());
92 FitSegmentList fitSegmentListW(slidingFitResultW.GetFitSegmentList());
93
94 for (unsigned int indexU = 0, indexUEnd = fitSegmentListU.size(); indexU < indexUEnd; ++indexU)
95 {
96 const FitSegment &fitSegmentU(fitSegmentListU.at(indexU));
97
98 for (unsigned int indexV = 0, indexVEnd = fitSegmentListV.size(); indexV < indexVEnd; ++indexV)
99 {
100 const FitSegment &fitSegmentV(fitSegmentListV.at(indexV));
101
102 for (unsigned int indexW = 0, indexWEnd = fitSegmentListW.size(); indexW < indexWEnd; ++indexW)
103 {
104 const FitSegment &fitSegmentW(fitSegmentListW.at(indexW));
105
106 TransverseOverlapResult segmentOverlap;
107 if (STATUS_CODE_SUCCESS != this->GetSegmentOverlap(fitSegmentU, fitSegmentV, fitSegmentW, slidingFitResultU,
108 slidingFitResultV, slidingFitResultW, segmentOverlap))
109 continue;
110
111 if ((segmentOverlap.GetMatchedFraction() < m_minSegmentMatchedFraction) ||
113 continue;
114
115 fitSegmentTensor[indexU][indexV][indexW] = segmentOverlap;
116 }
117 }
118 }
119}
120
121//------------------------------------------------------------------------------------------------------------------------------------------
122
124 const FitSegment &fitSegmentW, const TwoDSlidingFitResult &slidingFitResultU, const TwoDSlidingFitResult &slidingFitResultV,
125 const TwoDSlidingFitResult &slidingFitResultW, TransverseOverlapResult &transverseOverlapResult) const
126{
127 // Assess x-overlap
128 const float xSpanU(fitSegmentU.GetMaxX() - fitSegmentU.GetMinX());
129 const float xSpanV(fitSegmentV.GetMaxX() - fitSegmentV.GetMinX());
130 const float xSpanW(fitSegmentW.GetMaxX() - fitSegmentW.GetMinX());
131
132 const float minX(std::max(fitSegmentU.GetMinX(), std::max(fitSegmentV.GetMinX(), fitSegmentW.GetMinX())));
133 const float maxX(std::min(fitSegmentU.GetMaxX(), std::min(fitSegmentV.GetMaxX(), fitSegmentW.GetMaxX())));
134 const float xOverlap(maxX - minX);
135
136 if (xOverlap < std::numeric_limits<float>::epsilon())
137 return STATUS_CODE_NOT_FOUND;
138
139 // Sampling in x
140 const float nPointsU(std::fabs((xOverlap / xSpanU) * static_cast<float>(fitSegmentU.GetEndLayer() - fitSegmentU.GetStartLayer())));
141 const float nPointsV(std::fabs((xOverlap / xSpanV) * static_cast<float>(fitSegmentV.GetEndLayer() - fitSegmentV.GetStartLayer())));
142 const float nPointsW(std::fabs((xOverlap / xSpanW) * static_cast<float>(fitSegmentW.GetEndLayer() - fitSegmentW.GetStartLayer())));
143
144 const unsigned int nPoints(1 + static_cast<unsigned int>((nPointsU + nPointsV + nPointsW) / 3.f));
145
146 // Chi2 calculations
147 float pseudoChi2Sum(0.f);
148 unsigned int nSamplingPoints(0), nMatchedSamplingPoints(0);
149
150 for (unsigned int n = 0; n <= nPoints; ++n)
151 {
152 const float x(minX + (maxX - minX) * static_cast<float>(n) / static_cast<float>(nPoints));
153
154 CartesianVector fitUVector(0.f, 0.f, 0.f), fitVVector(0.f, 0.f, 0.f), fitWVector(0.f, 0.f, 0.f);
155 CartesianVector fitUDirection(0.f, 0.f, 0.f), fitVDirection(0.f, 0.f, 0.f), fitWDirection(0.f, 0.f, 0.f);
156
157 if ((STATUS_CODE_SUCCESS != slidingFitResultU.GetTransverseProjection(x, fitSegmentU, fitUVector, fitUDirection)) ||
158 (STATUS_CODE_SUCCESS != slidingFitResultV.GetTransverseProjection(x, fitSegmentV, fitVVector, fitVDirection)) ||
159 (STATUS_CODE_SUCCESS != slidingFitResultW.GetTransverseProjection(x, fitSegmentW, fitWVector, fitWDirection)))
160 {
161 continue;
162 }
163
164 const float u(fitUVector.GetZ()), v(fitVVector.GetZ()), w(fitWVector.GetZ());
165 const float uv2w(LArGeometryHelper::MergeTwoPositions(this->GetPandora(), TPC_VIEW_U, TPC_VIEW_V, u, v));
166 const float uw2v(LArGeometryHelper::MergeTwoPositions(this->GetPandora(), TPC_VIEW_U, TPC_VIEW_W, u, w));
167 const float vw2u(LArGeometryHelper::MergeTwoPositions(this->GetPandora(), TPC_VIEW_V, TPC_VIEW_W, v, w));
168
169 ++nSamplingPoints;
170 const float deltaU((vw2u - u) * fitUDirection.GetX());
171 const float deltaV((uw2v - v) * fitVDirection.GetX());
172 const float deltaW((uv2w - w) * fitWDirection.GetX());
173
174 const float pseudoChi2(deltaW * deltaW + deltaV * deltaV + deltaU * deltaU);
175 pseudoChi2Sum += pseudoChi2;
176
177 if (pseudoChi2 < m_pseudoChi2Cut)
178 ++nMatchedSamplingPoints;
179 }
180
181 if (0 == nSamplingPoints)
182 return STATUS_CODE_NOT_FOUND;
183
184 const XOverlap xOverlapObject(fitSegmentU.GetMinX(), fitSegmentU.GetMaxX(), fitSegmentV.GetMinX(), fitSegmentV.GetMaxX(),
185 fitSegmentW.GetMinX(), fitSegmentW.GetMaxX(), xOverlap);
186
187 transverseOverlapResult = TransverseOverlapResult(nMatchedSamplingPoints, nSamplingPoints, pseudoChi2Sum, xOverlapObject);
188 return STATUS_CODE_SUCCESS;
189}
190
191//------------------------------------------------------------------------------------------------------------------------------------------
192
194 const FitSegmentTensor &fitSegmentTensor, TransverseOverlapResult &bestTransverseOverlapResult) const
195{
196 if (fitSegmentTensor.empty())
197 {
198 bestTransverseOverlapResult = TransverseOverlapResult();
199 return;
200 }
201
202 unsigned int maxIndexU(0), maxIndexV(0), maxIndexW(0);
203 for (FitSegmentTensor::const_iterator tIter = fitSegmentTensor.begin(), tIterEnd = fitSegmentTensor.end(); tIter != tIterEnd; ++tIter)
204 {
205 maxIndexU = std::max(tIter->first, maxIndexU);
206
207 for (FitSegmentMatrix::const_iterator mIter = tIter->second.begin(), mIterEnd = tIter->second.end(); mIter != mIterEnd; ++mIter)
208 {
209 maxIndexV = std::max(mIter->first, maxIndexV);
210
211 for (FitSegmentToOverlapResultMap::const_iterator rIter = mIter->second.begin(), rIterEnd = mIter->second.end(); rIter != rIterEnd; ++rIter)
212 maxIndexW = std::max(rIter->first, maxIndexW);
213 }
214 }
215
216 // ATTN Protect against longitudinal tracks winding back and forth; can cause large number of memory allocations
217 maxIndexU = std::min(m_maxFitSegmentIndex, maxIndexU);
218 maxIndexV = std::min(m_maxFitSegmentIndex, maxIndexV);
219 maxIndexW = std::min(m_maxFitSegmentIndex, maxIndexW);
220
221 FitSegmentTensor fitSegmentSumTensor;
222 for (unsigned int indexU = 0; indexU <= maxIndexU; ++indexU)
223 {
224 for (unsigned int indexV = 0; indexV <= maxIndexV; ++indexV)
225 {
226 for (unsigned int indexW = 0; indexW <= maxIndexW; ++indexW)
227 {
228 TransverseOverlapResultVector transverseOverlapResultVector;
229 this->GetPreviousOverlapResults(indexU, indexV, indexW, fitSegmentSumTensor, transverseOverlapResultVector);
230
231 TransverseOverlapResultVector::const_iterator maxElement =
232 std::max_element(transverseOverlapResultVector.begin(), transverseOverlapResultVector.end());
233 TransverseOverlapResult maxTransverseOverlapResult(
234 (transverseOverlapResultVector.end() != maxElement) ? *maxElement : TransverseOverlapResult());
235
236 TransverseOverlapResult thisOverlapResult;
237 if (fitSegmentTensor.count(indexU) && (fitSegmentTensor.find(indexU))->second.count(indexV) &&
238 ((fitSegmentTensor.find(indexU))->second.find(indexV))->second.count(indexW))
239 thisOverlapResult = (((fitSegmentTensor.find(indexU))->second.find(indexV))->second.find(indexW))->second;
240
241 if (!thisOverlapResult.IsInitialized() && !maxTransverseOverlapResult.IsInitialized())
242 continue;
243
244 fitSegmentSumTensor[indexU][indexV][indexW] = thisOverlapResult + maxTransverseOverlapResult;
245 }
246 }
247 }
248
249 for (unsigned int indexU = 0; indexU <= maxIndexU; ++indexU)
250 {
251 for (unsigned int indexV = 0; indexV <= maxIndexV; ++indexV)
252 {
253 for (unsigned int indexW = 0; indexW <= maxIndexW; ++indexW)
254 {
255 const TransverseOverlapResult &transverseOverlapResult(fitSegmentSumTensor[indexU][indexV][indexW]);
256
257 if (!transverseOverlapResult.IsInitialized())
258 continue;
259
260 if (transverseOverlapResult > bestTransverseOverlapResult)
261 bestTransverseOverlapResult = transverseOverlapResult;
262 }
263 }
264 }
265}
266
267//------------------------------------------------------------------------------------------------------------------------------------------
268
269void ThreeViewTransverseTracksAlgorithm::GetPreviousOverlapResults(const unsigned int indexU, const unsigned int indexV,
270 const unsigned int indexW, FitSegmentTensor &fitSegmentSumTensor, TransverseOverlapResultVector &transverseOverlapResultVector) const
271{
272 for (unsigned int iPermutation = 1; iPermutation < 8; ++iPermutation)
273 {
274 const bool decrementU((iPermutation >> 0) & 0x1);
275 const bool decrementV((iPermutation >> 1) & 0x1);
276 const bool decrementW((iPermutation >> 2) & 0x1);
277
278 if ((decrementU && (0 == indexU)) || (decrementV && (0 == indexV)) || (decrementW && (0 == indexW)))
279 continue;
280
281 const unsigned int newIndexU(decrementU ? indexU - 1 : indexU);
282 const unsigned int newIndexV(decrementV ? indexV - 1 : indexV);
283 const unsigned int newIndexW(decrementW ? indexW - 1 : indexW);
284
285 const TransverseOverlapResult &transverseOverlapResult(fitSegmentSumTensor[newIndexU][newIndexV][newIndexW]);
286
287 if (transverseOverlapResult.IsInitialized())
288 transverseOverlapResultVector.push_back(transverseOverlapResult);
289 }
290
291 if (transverseOverlapResultVector.empty())
292 transverseOverlapResultVector.push_back(TransverseOverlapResult());
293}
294
295//------------------------------------------------------------------------------------------------------------------------------------------
296
298{
299 unsigned int repeatCounter(0);
300
301 for (TensorToolVector::const_iterator iter = m_algorithmToolVector.begin(), iterEnd = m_algorithmToolVector.end(); iter != iterEnd;)
302 {
303 if ((*iter)->Run(this, this->GetMatchingControl().GetOverlapTensor()))
304 {
305 iter = m_algorithmToolVector.begin();
306
307 if (++repeatCounter > m_nMaxTensorToolRepeats)
308 break;
309 }
310 else
311 {
312 ++iter;
313 }
314 }
315}
316
317//------------------------------------------------------------------------------------------------------------------------------------------
318//------------------------------------------------------------------------------------------------------------------------------------------
319
321{
322 AlgorithmToolVector algorithmToolVector;
323 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmToolList(*this, xmlHandle, "TrackTools", algorithmToolVector));
324
325 for (AlgorithmToolVector::const_iterator iter = algorithmToolVector.begin(), iterEnd = algorithmToolVector.end(); iter != iterEnd; ++iter)
326 {
327 TransverseTensorTool *const pTransverseTensorTool(dynamic_cast<TransverseTensorTool *>(*iter));
328
329 if (!pTransverseTensorTool)
330 return STATUS_CODE_INVALID_PARAMETER;
331
332 m_algorithmToolVector.push_back(pTransverseTensorTool);
333 }
334
336 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "NMaxTensorToolRepeats", m_nMaxTensorToolRepeats));
337
339 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxFitSegmentIndex", m_maxFitSegmentIndex));
340
341 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "PseudoChi2Cut", m_pseudoChi2Cut));
342
343 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
344 XmlHelper::ReadValue(xmlHandle, "MinSegmentMatchedFraction", m_minSegmentMatchedFraction));
345
346 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
347 XmlHelper::ReadValue(xmlHandle, "MinSegmentMatchedPoints", m_minSegmentMatchedPoints));
348
349 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
350 XmlHelper::ReadValue(xmlHandle, "MinOverallMatchedFraction", m_minOverallMatchedFraction));
351
352 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
353 XmlHelper::ReadValue(xmlHandle, "MinOverallMatchedPoints", m_minOverallMatchedPoints));
354
355 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
356 XmlHelper::ReadValue(xmlHandle, "MinSamplingPointsPerLayer", m_minSamplingPointsPerLayer));
357
358 return BaseAlgorithm::ReadSettings(xmlHandle);
359}
360
361} // 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_THROW_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
Definition StatusCodes.h:55
#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 three view transverse tracks algorithm class.
int GetEndLayer() const
Get end layer.
double GetMaxX() const
Get the maximum x value.
int GetStartLayer() const
Get start layer.
double GetMinX() const
Get the minimum x value.
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).
MatchingType & GetMatchingControl()
Get the matching control.
const TwoDSlidingFitResult & GetCachedSlidingFitResult(const pandora::Cluster *const pCluster) const
Get a sliding fit result from the algorithm cache.
std::map< unsigned int, FitSegmentMatrix > FitSegmentTensor
float m_minSamplingPointsPerLayer
The minimum number of sampling points per layer to allow particle creation.
float m_minOverallMatchedFraction
The minimum matched sampling fraction to allow particle creation.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
void CalculateOverlapResult(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV, const pandora::Cluster *const pClusterW)
Calculate cluster overlap result and store in container.
void ExamineOverlapContainer()
Examine contents of overlap container, collect together best-matching 2D particles and modify cluster...
unsigned int m_maxFitSegmentIndex
The maximum number of fit segments used when identifying best overlap result.
void GetFitSegmentTensor(const TwoDSlidingFitResult &slidingFitResultU, const TwoDSlidingFitResult &slidingFitResultV, const TwoDSlidingFitResult &slidingFitResultW, FitSegmentTensor &fitSegmentTensor) const
Get the number of matched points for three fit segments and accompanying sliding fit results.
unsigned int m_nMaxTensorToolRepeats
The maximum number of repeat loops over tensor tools.
void GetPreviousOverlapResults(const unsigned int indexU, const unsigned int indexV, const unsigned int indexW, FitSegmentTensor &fitSegmentSumTensor, TransverseOverlapResultVector &transverseOverlapResultVector) const
Get track overlap results for possible connected segments.
float m_minSegmentMatchedFraction
The minimum segment matched sampling fraction to allow segment grouping.
void GetBestOverlapResult(const FitSegmentTensor &fitSegmentTensor, TransverseOverlapResult &bestTransverseOverlapResult) const
Get the best overlap result, by examining the fit segment tensor.
pandora::StatusCode GetSegmentOverlap(const FitSegment &fitSegmentU, const FitSegment &fitSegmentV, const FitSegment &fitSegmentW, const TwoDSlidingFitResult &slidingFitResultU, const TwoDSlidingFitResult &slidingFitResultV, const TwoDSlidingFitResult &slidingFitResultW, TransverseOverlapResult &transverseOverlapResult) const
Get the overlap result for three fit segments and the accompanying sliding fit results.
TensorToolVector m_algorithmToolVector
The algorithm tool vector.
float m_pseudoChi2Cut
The pseudo chi2 cut to identify matched sampling points.
unsigned int m_minOverallMatchedPoints
The minimum number of matched segment sampling points to allow particle creation.
unsigned int m_minSegmentMatchedPoints
The minimum number of matched segment sampling points to allow segment grouping.
unsigned int GetNSamplingPoints() const
Get the number of sampling points.
bool IsInitialized() const
Whether the track overlap result has been initialized.
unsigned int GetNMatchedSamplingPoints() const
Get the number of matched sampling points.
float GetMatchedFraction() const
Get the fraction of sampling points resulting in a match.
const FitSegmentList & GetFitSegmentList() const
Get the fit segment list.
int GetMaxLayer() const
Get the maximum occupied layer in the sliding fit.
int GetMinLayer() const
Get the minimum occupied layer in the sliding fit.
pandora::StatusCode GetTransverseProjection(const float x, const FitSegment &fitSegment, pandora::CartesianVector &position) const
Get projected position for a given input x coordinate and fit segment.
XOverlap class.
Definition LArXOverlap.h:18
CartesianVector class.
float GetX() const
Get the cartesian x coordinate.
float GetZ() const
Get the cartesian z coordinate.
Cluster class.
Definition Cluster.h:31
const Pandora & GetPandora() const
Get the associated pandora instance.
Definition Process.h:116
static StatusCode ReadValue(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, T &t)
Read a value from an xml element.
Definition XmlHelper.h:136
static StatusCode ProcessAlgorithmToolList(const Algorithm &algorithm, const TiXmlHandle &xmlHandle, const std::string &listName, AlgorithmToolVector &algorithmToolVector)
Process a list of algorithms tools in an xml file.
Definition XmlHelper.cc:101
std::vector< FitSegment > FitSegmentList
std::vector< TransverseOverlapResult > TransverseOverlapResultVector
std::vector< AlgorithmTool * > AlgorithmToolVector
StatusCode
The StatusCode enum.