9 #include "Pandora/AlgorithmHeaders.h"
21 ThreeViewTransverseTracksAlgorithm::ThreeViewTransverseTracksAlgorithm() :
22 m_nMaxTensorToolRepeats(1000),
23 m_maxFitSegmentIndex(50),
25 m_minSegmentMatchedFraction(0.1f),
26 m_minSegmentMatchedPoints(3),
27 m_minOverallMatchedFraction(0.5f),
28 m_minOverallMatchedPoints(10),
29 m_minSamplingPointsPerLayer(0.1f)
38 PANDORA_THROW_RESULT_IF_AND_IF(
39 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, this->
CalculateOverlapResult(pClusterU, pClusterV, pClusterW, overlapResult));
48 const Cluster *
const pClusterU,
const Cluster *
const pClusterV,
const Cluster *
const pClusterW, TransverseOverlapResult &overlapResult)
55 this->
GetFitSegmentTensor(slidingFitResultU, slidingFitResultV, slidingFitResultW, fitSegmentTensor);
57 TransverseOverlapResult transverseOverlapResult;
60 if (!transverseOverlapResult.IsInitialized())
61 return STATUS_CODE_NOT_FOUND;
65 return STATUS_CODE_NOT_FOUND;
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)));
73 if (0 == meanLayersSpanned)
74 return STATUS_CODE_FAILURE;
76 const float nSamplingPointsPerLayer(static_cast<float>(transverseOverlapResult.GetNSamplingPoints()) / static_cast<float>(meanLayersSpanned));
79 return STATUS_CODE_NOT_FOUND;
81 overlapResult = transverseOverlapResult;
82 return STATUS_CODE_SUCCESS;
94 for (
unsigned int indexU = 0, indexUEnd = fitSegmentListU.size(); indexU < indexUEnd; ++indexU)
96 const FitSegment &fitSegmentU(fitSegmentListU.at(indexU));
98 for (
unsigned int indexV = 0, indexVEnd = fitSegmentListV.size(); indexV < indexVEnd; ++indexV)
100 const FitSegment &fitSegmentV(fitSegmentListV.at(indexV));
102 for (
unsigned int indexW = 0, indexWEnd = fitSegmentListW.size(); indexW < indexWEnd; ++indexW)
104 const FitSegment &fitSegmentW(fitSegmentListW.at(indexW));
107 if (STATUS_CODE_SUCCESS != this->
GetSegmentOverlap(fitSegmentU, fitSegmentV, fitSegmentW, slidingFitResultU,
108 slidingFitResultV, slidingFitResultW, segmentOverlap))
115 fitSegmentTensor[indexU][indexV][indexW] = segmentOverlap;
128 const float xSpanU(fitSegmentU.
GetMaxX() - fitSegmentU.
GetMinX());
129 const float xSpanV(fitSegmentV.
GetMaxX() - fitSegmentV.
GetMinX());
130 const float xSpanW(fitSegmentW.
GetMaxX() - fitSegmentW.
GetMinX());
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);
136 if (xOverlap < std::numeric_limits<float>::epsilon())
137 return STATUS_CODE_NOT_FOUND;
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())));
144 const unsigned int nPoints(1 + static_cast<unsigned int>((nPointsU + nPointsV + nPointsW) / 3.f));
147 float pseudoChi2Sum(0.f);
148 unsigned int nSamplingPoints(0), nMatchedSamplingPoints(0);
150 for (
unsigned int n = 0;
n <= nPoints; ++
n)
152 const float x(minX + (maxX - minX) * static_cast<float>(
n) / static_cast<float>(nPoints));
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);
157 if ((STATUS_CODE_SUCCESS != slidingFitResultU.
GetTransverseProjection(x, fitSegmentU, fitUVector, fitUDirection)) ||
158 (STATUS_CODE_SUCCESS != slidingFitResultV.
GetTransverseProjection(x, fitSegmentV, fitVVector, fitVDirection)) ||
164 const float u(fitUVector.GetZ()), v(fitVVector.GetZ()),
w(fitWVector.GetZ());
170 const float deltaU((vw2u - u) * fitUDirection.GetX());
171 const float deltaV((uw2v - v) * fitVDirection.GetX());
172 const float deltaW((uv2w -
w) * fitWDirection.GetX());
174 const float pseudoChi2(deltaW * deltaW + deltaV * deltaV + deltaU * deltaU);
175 pseudoChi2Sum += pseudoChi2;
178 ++nMatchedSamplingPoints;
181 if (0 == nSamplingPoints)
182 return STATUS_CODE_NOT_FOUND;
187 transverseOverlapResult =
TransverseOverlapResult(nMatchedSamplingPoints, nSamplingPoints, pseudoChi2Sum, xOverlapObject);
188 return STATUS_CODE_SUCCESS;
196 if (fitSegmentTensor.empty())
202 unsigned int maxIndexU(0), maxIndexV(0), maxIndexW(0);
203 for (FitSegmentTensor::const_iterator tIter = fitSegmentTensor.begin(), tIterEnd = fitSegmentTensor.end(); tIter != tIterEnd; ++tIter)
205 maxIndexU = std::max(tIter->first, maxIndexU);
207 for (FitSegmentMatrix::const_iterator mIter = tIter->second.begin(), mIterEnd = tIter->second.end(); mIter != mIterEnd; ++mIter)
209 maxIndexV = std::max(mIter->first, maxIndexV);
211 for (FitSegmentToOverlapResultMap::const_iterator rIter = mIter->second.begin(), rIterEnd = mIter->second.end(); rIter != rIterEnd; ++rIter)
212 maxIndexW = std::max(rIter->first, maxIndexW);
222 for (
unsigned int indexU = 0; indexU <= maxIndexU; ++indexU)
224 for (
unsigned int indexV = 0; indexV <= maxIndexV; ++indexV)
226 for (
unsigned int indexW = 0; indexW <= maxIndexW; ++indexW)
231 TransverseOverlapResultVector::const_iterator maxElement =
232 std::max_element(transverseOverlapResultVector.begin(), transverseOverlapResultVector.end());
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;
241 if (!thisOverlapResult.IsInitialized() && !maxTransverseOverlapResult.IsInitialized())
244 fitSegmentSumTensor[indexU][indexV][indexW] = thisOverlapResult + maxTransverseOverlapResult;
249 for (
unsigned int indexU = 0; indexU <= maxIndexU; ++indexU)
251 for (
unsigned int indexV = 0; indexV <= maxIndexV; ++indexV)
253 for (
unsigned int indexW = 0; indexW <= maxIndexW; ++indexW)
260 if (transverseOverlapResult > bestTransverseOverlapResult)
261 bestTransverseOverlapResult = transverseOverlapResult;
272 for (
unsigned int iPermutation = 1; iPermutation < 8; ++iPermutation)
274 const bool decrementU((iPermutation >> 0) & 0x1);
275 const bool decrementV((iPermutation >> 1) & 0x1);
276 const bool decrementW((iPermutation >> 2) & 0x1);
278 if ((decrementU && (0 == indexU)) || (decrementV && (0 == indexV)) || (decrementW && (0 == indexW)))
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);
288 transverseOverlapResultVector.push_back(transverseOverlapResult);
291 if (transverseOverlapResultVector.empty())
299 unsigned int repeatCounter(0);
303 if ((*iter)->Run(
this,
this->GetMatchingControl().GetOverlapTensor()))
322 AlgorithmToolVector algorithmToolVector;
323 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmToolList(*
this, xmlHandle,
"TrackTools", algorithmToolVector));
325 for (AlgorithmToolVector::const_iterator iter = algorithmToolVector.begin(), iterEnd = algorithmToolVector.end(); iter != iterEnd; ++iter)
329 if (!pTransverseTensorTool)
330 return STATUS_CODE_INVALID_PARAMETER;
335 PANDORA_RETURN_RESULT_IF_AND_IF(
336 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"NMaxTensorToolRepeats",
m_nMaxTensorToolRepeats));
338 PANDORA_RETURN_RESULT_IF_AND_IF(
339 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MaxFitSegmentIndex",
m_maxFitSegmentIndex));
341 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"PseudoChi2Cut",
m_pseudoChi2Cut));
343 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
346 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
349 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
352 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
355 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
int GetStartLayer() const
Get start layer.
process_name opflash particleana ie x
TensorType & GetOverlapTensor()
Get the overlap tensor.
std::map< unsigned int, FitSegmentMatrix > FitSegmentTensor
bool IsInitialized() const
Whether the track overlap result has been initialized.
const TwoDSlidingFitResult & GetCachedSlidingFitResult(const pandora::Cluster *const pCluster) const
Get a sliding fit result from the algorithm cache.
float m_minSegmentMatchedFraction
The minimum segment matched sampling fraction to allow segment grouping.
float m_minOverallMatchedFraction
The minimum matched sampling fraction to allow particle creation.
std::vector< FitSegment > FitSegmentList
float m_pseudoChi2Cut
The pseudo chi2 cut to identify matched sampling points.
std::vector< TransverseOverlapResult > TransverseOverlapResultVector
MatchingType & GetMatchingControl()
Get the matching control.
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.
Header file for the geometry helper class.
float m_minSamplingPointsPerLayer
The minimum number of sampling points per layer to allow particle creation.
void SetOverlapResult(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV, const pandora::Cluster *const pClusterW, const OverlapResult &overlapResult)
Set overlap result.
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.
Header file for the cluster helper class.
Header file for the three view transverse tracks algorithm class.
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).
const FitSegmentList & GetFitSegmentList() const
Get the fit segment list.
TransverseOverlapResult class.
unsigned int m_minSegmentMatchedPoints
The minimum number of matched segment sampling points to allow segment grouping.
TensorToolVector m_algorithmToolVector
The algorithm tool vector.
TransverseTensorTool class.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
unsigned int m_maxFitSegmentIndex
The maximum number of fit segments used when identifying best overlap result.
double GetMinX() const
Get the minimum x value.
unsigned int m_minOverallMatchedPoints
The minimum number of matched segment sampling points to allow particle creation. ...
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.
unsigned int m_nMaxTensorToolRepeats
The maximum number of repeat loops over tensor tools.
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...
void ExamineOverlapContainer()
Examine contents of overlap container, collect together best-matching 2D particles and modify cluster...
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.
int GetEndLayer() const
Get end layer.
TwoDSlidingFitResult class.
double GetMaxX() const
Get the maximum x value.
void GetBestOverlapResult(const FitSegmentTensor &fitSegmentTensor, TransverseOverlapResult &bestTransverseOverlapResult) const
Get the best overlap result, by examining the fit segment tensor.