9 #include "Pandora/AlgorithmHeaders.h"
21 ThreeViewLongitudinalTracksAlgorithm::ThreeViewLongitudinalTracksAlgorithm() :
22 m_nMaxTensorToolRepeats(1000),
23 m_vertexChi2Cut(10.f),
24 m_reducedChi2Cut(5.f),
32 const Cluster *
const pClusterU,
const Cluster *
const pClusterV,
const Cluster *
const pClusterW)
44 const Cluster *
const pClusterW, LongitudinalOverlapResult &longitudinalOverlapResult)
51 TrackOverlapResult bestOverlapResult;
53 for (
unsigned int iPermutation = 0; iPermutation < 4; ++iPermutation)
55 const bool isForwardU((1 == iPermutation) ?
false :
true);
56 const bool isForwardV((2 == iPermutation) ?
false :
true);
57 const bool isForwardW((3 == iPermutation) ?
false :
true);
60 const CartesianVector vtxU((isForwardU) ? slidingFitResultU.GetGlobalMinLayerPosition() : slidingFitResultU.GetGlobalMaxLayerPosition());
61 const CartesianVector endU((!isForwardU) ? slidingFitResultU.GetGlobalMinLayerPosition() : slidingFitResultU.GetGlobalMaxLayerPosition());
63 const CartesianVector vtxV((isForwardV) ? slidingFitResultV.GetGlobalMinLayerPosition() : slidingFitResultV.GetGlobalMaxLayerPosition());
64 const CartesianVector endV((!isForwardV) ? slidingFitResultV.GetGlobalMinLayerPosition() : slidingFitResultV.GetGlobalMaxLayerPosition());
66 const CartesianVector vtxW((isForwardW) ? slidingFitResultW.GetGlobalMinLayerPosition() : slidingFitResultW.GetGlobalMaxLayerPosition());
67 const CartesianVector endW((!isForwardW) ? slidingFitResultW.GetGlobalMinLayerPosition() : slidingFitResultW.GetGlobalMaxLayerPosition());
70 const float halfLengthSquaredU(0.25 * (vtxU - endU).GetMagnitudeSquared());
71 const float halfLengthSquaredV(0.25 * (vtxV - endV).GetMagnitudeSquared());
72 const float halfLengthSquaredW(0.25 * (vtxW - endW).GetMagnitudeSquared());
74 CartesianVector vtxMergedU(0.f, 0.f, 0.f), vtxMergedV(0.f, 0.f, 0.f), vtxMergedW(0.f, 0.f, 0.f);
75 CartesianVector endMergedU(0.f, 0.f, 0.f), endMergedV(0.f, 0.f, 0.f), endMergedW(0.f, 0.f, 0.f);
77 float vtxChi2(std::numeric_limits<float>::max());
78 float endChi2(std::numeric_limits<float>::max());
81 this->GetPandora(), TPC_VIEW_U, TPC_VIEW_V, TPC_VIEW_W, vtxU, vtxV, vtxW, vtxMergedU, vtxMergedV, vtxMergedW, vtxChi2);
86 if (((vtxMergedU - vtxU).GetMagnitudeSquared() > std::min(halfLengthSquaredU, (vtxMergedU - endU).GetMagnitudeSquared())) ||
87 ((vtxMergedV - vtxV).GetMagnitudeSquared() > std::min(halfLengthSquaredV, (vtxMergedV - endV).GetMagnitudeSquared())) ||
88 ((vtxMergedW - vtxW).GetMagnitudeSquared() > std::min(halfLengthSquaredW, (vtxMergedW - endW).GetMagnitudeSquared())))
92 this->GetPandora(), TPC_VIEW_U, TPC_VIEW_V, TPC_VIEW_W, endU, endV, endW, endMergedU, endMergedV, endMergedW, endChi2);
97 if (((endMergedU - endU).GetMagnitudeSquared() > std::min(halfLengthSquaredU, (endMergedU - vtxU).GetMagnitudeSquared())) ||
98 ((endMergedV - endV).GetMagnitudeSquared() > std::min(halfLengthSquaredV, (endMergedV - vtxV).GetMagnitudeSquared())) ||
99 ((endMergedW - endW).GetMagnitudeSquared() > std::min(halfLengthSquaredW, (endMergedW - vtxW).GetMagnitudeSquared())))
104 CartesianVector position3D(0.f, 0.f, 0.f);
105 CartesianPointVector vtxList3D, endList3D;
108 vtxList3D.push_back(position3D);
111 vtxList3D.push_back(position3D);
114 vtxList3D.push_back(position3D);
117 endList3D.push_back(position3D);
120 endList3D.push_back(position3D);
123 endList3D.push_back(position3D);
126 for (CartesianPointVector::const_iterator iterI = vtxList3D.begin(), iterEndI = vtxList3D.end(); iterI != iterEndI; ++iterI)
128 const CartesianVector &vtxMerged3D(*iterI);
130 for (CartesianPointVector::const_iterator iterJ = endList3D.begin(), iterEndJ = endList3D.end(); iterJ != iterEndJ; ++iterJ)
132 const CartesianVector &endMerged3D(*iterJ);
134 TrackOverlapResult overlapResult;
135 this->
CalculateOverlapResult(slidingFitResultU, slidingFitResultV, slidingFitResultW, vtxMerged3D, endMerged3D, overlapResult);
137 if (overlapResult.IsInitialized() && (overlapResult.GetNMatchedSamplingPoints() > 0) && (overlapResult > bestOverlapResult))
139 bestOverlapResult = overlapResult;
140 longitudinalOverlapResult = LongitudinalOverlapResult(overlapResult, vtxChi2, endChi2);
150 const TwoDSlidingFitResult &slidingFitResultV,
const TwoDSlidingFitResult &slidingFitResultW,
const CartesianVector &vtxMerged3D,
151 const CartesianVector &endMerged3D, TrackOverlapResult &overlapResult)
const
162 const unsigned int nSamplingPoints =
static_cast<unsigned int>((endMerged3D - vtxMerged3D).GetMagnitude() /
m_samplingPitch);
164 if (0 == nSamplingPoints)
168 float deltaChi2(0.f), totalChi2(0.f);
169 unsigned int nMatchedSamplingPoints(0);
171 for (
unsigned int n = 0;
n < nSamplingPoints; ++
n)
173 const float alpha((0.5f + static_cast<float>(
n)) / static_cast<float>(nSamplingPoints));
174 const CartesianVector linearU(vtxMergedU + (endMergedU - vtxMergedU) * alpha);
175 const CartesianVector linearV(vtxMergedV + (endMergedV - vtxMergedV) * alpha);
176 const CartesianVector linearW(vtxMergedW + (endMergedW - vtxMergedW) * alpha);
178 CartesianVector posU(0.f, 0.f, 0.f), posV(0.f, 0.f, 0.f), posW(0.f, 0.f, 0.f);
179 if ((STATUS_CODE_SUCCESS != slidingFitResultU.GetGlobalFitProjection(linearU, posU)) ||
180 (STATUS_CODE_SUCCESS != slidingFitResultV.GetGlobalFitProjection(linearV, posV)) ||
181 (STATUS_CODE_SUCCESS != slidingFitResultW.GetGlobalFitProjection(linearW, posW)))
186 CartesianVector mergedU(0.f, 0.f, 0.f), mergedV(0.f, 0.f, 0.f), mergedW(0.f, 0.f, 0.f);
190 ++nMatchedSamplingPoints;
192 totalChi2 += deltaChi2;
195 if (nMatchedSamplingPoints > 0)
196 overlapResult = TrackOverlapResult(nMatchedSamplingPoints, nSamplingPoints, totalChi2);
203 unsigned int repeatCounter(0);
207 if ((*iter)->Run(
this,
this->GetMatchingControl().GetOverlapTensor()))
225 AlgorithmToolVector algorithmToolVector;
226 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmToolList(*
this, xmlHandle,
"TrackTools", algorithmToolVector));
228 for (AlgorithmToolVector::const_iterator iter = algorithmToolVector.begin(), iterEnd = algorithmToolVector.end(); iter != iterEnd; ++iter)
232 if (!pLongitudinalTensorTool)
233 return STATUS_CODE_INVALID_PARAMETER;
238 PANDORA_RETURN_RESULT_IF_AND_IF(
239 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"NMaxTensorToolRepeats",
m_nMaxTensorToolRepeats));
241 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"VertexChi2Cut",
m_vertexChi2Cut));
243 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"ReducedChi2Cut",
m_reducedChi2Cut));
245 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SamplingPitch",
m_samplingPitch));
248 return STATUS_CODE_INVALID_PARAMETER;
LongitudinalOverlapResult class.
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static void MergeTwoPositions3D(const pandora::Pandora &pandora, const pandora::HitType view1, const pandora::HitType view2, const pandora::CartesianVector &position1, const pandora::CartesianVector &position2, pandora::CartesianVector &position3D, float &chiSquared)
Merge 2D positions from two views to give unified 3D position.
TensorType & GetOverlapTensor()
Get the overlap tensor.
void ExamineOverlapContainer()
Examine contents of overlap container, collect together best-matching 2D particles and modify cluster...
bool IsInitialized() const
Whether the track overlap result has been initialized.
unsigned int m_nMaxTensorToolRepeats
The maximum number of repeat loops over tensor tools.
const TwoDSlidingFitResult & GetCachedSlidingFitResult(const pandora::Cluster *const pCluster) const
Get a sliding fit result from the algorithm cache.
static pandora::CartesianVector ProjectPosition(const pandora::Pandora &pandora, const pandora::CartesianVector &position3D, const pandora::HitType view)
Project 3D position into a given 2D view.
MatchingType & GetMatchingControl()
Get the matching control.
Header file for the geometry helper class.
void SetOverlapResult(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV, const pandora::Cluster *const pClusterW, const OverlapResult &overlapResult)
Set overlap result.
Header file for the cluster helper class.
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.
float m_samplingPitch
Pitch used to generate sampling points along tracks.
TensorToolVector m_algorithmToolVector
The algorithm tool vector.
static void MergeThreePositions(const pandora::Pandora &pandora, const pandora::HitType view1, const pandora::HitType view2, const pandora::HitType view3, const pandora::CartesianVector &position1, const pandora::CartesianVector &position2, const pandora::CartesianVector &position3, pandora::CartesianVector &outputU, pandora::CartesianVector &outputV, pandora::CartesianVector &outputW, float &chiSquared)
Merge 2D positions from three views to give unified 2D positions for each view.
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
LongitudinalTensorTool class.
float m_vertexChi2Cut
The maximum allowed chi2 for associating end points from three views.
Header file for the three view longitudinal tracks algorithm class.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
float m_reducedChi2Cut
The maximum allowed chi2 for associating hit positions from three views.